diff --git a/packages/super-sync-server/docker-compose.build.yml b/packages/super-sync-server/docker-compose.build.yml new file mode 100644 index 0000000000..a19e527b0c --- /dev/null +++ b/packages/super-sync-server/docker-compose.build.yml @@ -0,0 +1,11 @@ +# Local build override for development +# +# Usage: +# docker-compose -f docker-compose.yml -f docker-compose.build.yml up -d --build + +services: + supersync: + build: + context: ../.. + dockerfile: packages/super-sync-server/Dockerfile + image: supersync:local diff --git a/packages/super-sync-server/docker-compose.yml b/packages/super-sync-server/docker-compose.yml index c828443d7a..22c815f229 100644 --- a/packages/super-sync-server/docker-compose.yml +++ b/packages/super-sync-server/docker-compose.yml @@ -5,8 +5,8 @@ # 2. Run: docker-compose up -d # 3. View logs: docker-compose logs -f # -# Build from repo root: -# docker-compose -f packages/super-sync-server/docker-compose.yml up -d --build +# For local builds (development): +# docker-compose -f docker-compose.yml -f docker-compose.build.yml up -d --build x-logging: &default-logging driver: 'json-file' @@ -16,10 +16,7 @@ x-logging: &default-logging services: supersync: - build: - context: ../.. - dockerfile: packages/super-sync-server/Dockerfile - image: supersync:v4 + image: ${SUPERSYNC_IMAGE:-ghcr.io/johannesjo/supersync:latest} container_name: supersync-server restart: always environment: diff --git a/packages/super-sync-server/env.example b/packages/super-sync-server/env.example index f9a37a550d..09190f686d 100644 --- a/packages/super-sync-server/env.example +++ b/packages/super-sync-server/env.example @@ -56,6 +56,17 @@ SMTP_PASS=your-smtp-password # From address for emails SMTP_FROM="Super Productivity Sync" +# ============================================================================= +# CONTAINER REGISTRY (for build-and-push.sh) +# ============================================================================= + +# GitHub username for GHCR +GHCR_USER=your-github-username + +# GitHub token with "Packages: Read and write" permission +# Create at: https://github.com/settings/tokens?type=beta +GHCR_TOKEN=your-github-token + # ============================================================================= # ADVANCED SETTINGS (usually no changes needed) # ============================================================================= diff --git a/packages/super-sync-server/package.json b/packages/super-sync-server/package.json index 469773e02f..551776d038 100644 --- a/packages/super-sync-server/package.json +++ b/packages/super-sync-server/package.json @@ -4,16 +4,18 @@ "description": "SuperSync server for Super Productivity", "main": "dist/index.js", "scripts": { - "deploy": "git pull && docker compose down && docker compose up -d --build && docker logs supersync-server", "build": "tsc", - "start": "docker compose down && docker compose up -d --build", - "start2": "node dist/index.js", + "start": "node dist/index.js", "dev": "nodemon --watch src --ext ts --exec ts-node src/index.ts", "test": "vitest run", + "docker:build": "./scripts/build-and-push.sh", + "docker:deploy": "./scripts/deploy.sh", + "docker:deploy:build": "./scripts/deploy.sh --build", + "docker:backup": "./scripts/backup.sh", + "docker:logs": "docker logs supersync-server -f", "delete-user": "ts-node scripts/delete-user.ts", "clear-data": "ts-node scripts/clear-data.ts", - "monitor": "ts-node scripts/monitor.ts", - "logs": "docker logs supersync-server -f" + "monitor": "ts-node scripts/monitor.ts" }, "dependencies": { "@fastify/cors": "^11.1.0", diff --git a/packages/super-sync-server/scripts/build-and-push.sh b/packages/super-sync-server/scripts/build-and-push.sh new file mode 100755 index 0000000000..3b8d8936c3 --- /dev/null +++ b/packages/super-sync-server/scripts/build-and-push.sh @@ -0,0 +1,74 @@ +#!/bin/bash +# SuperSync Server - Build and Push to GitHub Container Registry +# +# Usage: +# ./scripts/build-and-push.sh [TAG] +# +# Examples: +# ./scripts/build-and-push.sh # Pushes as :latest +# ./scripts/build-and-push.sh v1.0.0 # Pushes as :v1.0.0 and :latest +# +# Prerequisites: +# Add to .env file: +# GHCR_USER=your-github-username +# GHCR_TOKEN=your-github-token + +set -e + +# Get script directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SERVER_DIR="$(dirname "$SCRIPT_DIR")" +REPO_ROOT="$(dirname "$(dirname "$SERVER_DIR")")" +DOCKERFILE="$SERVER_DIR/Dockerfile" + +# Load .env file +if [ -f "$SERVER_DIR/.env" ]; then + export $(grep -E '^(GHCR_USER|GHCR_TOKEN)=' "$SERVER_DIR/.env" | xargs) +fi + +# Configuration +GITHUB_USER="${GHCR_USER:-johannesjo}" +GHCR_TOKEN="${GHCR_TOKEN:-}" +IMAGE_NAME="ghcr.io/$GITHUB_USER/supersync" + +# Parse tag argument +TAG="${1:-latest}" + +echo "==> SuperSync Build & Push" +echo " Image: $IMAGE_NAME:$TAG" +echo " Repo: $REPO_ROOT" +echo "" + +# Step 1: Build image +echo "==> Building image..." +docker build \ + -t "$IMAGE_NAME:$TAG" \ + -t "$IMAGE_NAME:latest" \ + -f "$DOCKERFILE" \ + "$REPO_ROOT" + +echo "" +echo "==> Build complete!" +echo "" + +# Step 2: Login to GHCR (if token provided) +if [ -n "$GHCR_TOKEN" ]; then + echo "==> Logging in to GHCR..." + echo "$GHCR_TOKEN" | docker login ghcr.io -u "$GITHUB_USER" --password-stdin + echo "" +fi + +# Step 3: Push to registry +echo "==> Pushing to GHCR..." +docker push "$IMAGE_NAME:$TAG" + +if [ "$TAG" != "latest" ]; then + docker push "$IMAGE_NAME:latest" +fi + +echo "" +echo "==> Done!" +echo " Pushed: $IMAGE_NAME:$TAG" +echo "" +echo " To deploy on server, run:" +echo " ./scripts/deploy.sh" diff --git a/packages/super-sync-server/scripts/deploy.sh b/packages/super-sync-server/scripts/deploy.sh index 61f7f6075f..e5e77c7855 100755 --- a/packages/super-sync-server/scripts/deploy.sh +++ b/packages/super-sync-server/scripts/deploy.sh @@ -2,22 +2,21 @@ # SuperSync Server Deployment Script # # Usage: -# ./scripts/deploy.sh [--force] +# ./scripts/deploy.sh [--build] # # This script: -# 1. Pulls latest changes from git -# 2. Rebuilds and restarts containers +# 1. Pulls latest image from GHCR (or builds locally with --build) +# 2. Restarts containers # 3. Verifies health check passes # # Options: -# --force Force rebuild without cache +# --build Build locally instead of pulling from registry set -e # Configuration SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SERVER_DIR="$(dirname "$SCRIPT_DIR")" -REPO_DIR="$(dirname "$(dirname "$SERVER_DIR")")" # Get domain from .env file if [ -f "$SERVER_DIR/.env" ]; then @@ -32,9 +31,9 @@ else fi # Parse arguments -FORCE_BUILD="" -if [ "$1" = "--force" ]; then - FORCE_BUILD="--no-cache" +BUILD_LOCAL=false +if [ "$1" = "--build" ]; then + BUILD_LOCAL=true fi echo "==> SuperSync Deployment" @@ -42,14 +41,6 @@ echo " Server dir: $SERVER_DIR" echo " Health URL: $HEALTH_URL" echo "" -# Step 1: Pull latest changes -echo "==> Pulling latest changes..." -cd "$REPO_DIR" -git pull origin "$(git rev-parse --abbrev-ref HEAD)" - -# Step 2: Build and restart -echo "" -echo "==> Building and restarting containers..." cd "$SERVER_DIR" # Check if monitoring compose exists and include it @@ -58,9 +49,22 @@ if [ -f "docker-compose.monitoring.yml" ]; then COMPOSE_FILES="$COMPOSE_FILES -f docker-compose.monitoring.yml" fi -docker compose $COMPOSE_FILES up -d --build $FORCE_BUILD +if [ "$BUILD_LOCAL" = true ]; then + # Local build mode + echo "==> Building locally..." + COMPOSE_FILES="$COMPOSE_FILES -f docker-compose.build.yml" + docker compose $COMPOSE_FILES up -d --build +else + # Pull from registry (default) + echo "==> Pulling latest image..." + docker compose $COMPOSE_FILES pull supersync -# Step 3: Wait for health check + echo "" + echo "==> Restarting containers..." + docker compose $COMPOSE_FILES up -d +fi + +# Wait for health check echo "" echo "==> Waiting for service to be healthy..." sleep 5