See the best posts from any Bluesky account
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Migrate from Docker Compose to Docker Swarm for zero-downtime deploys

Convert docker-compose.yml to Swarm-compatible format (deploy sections
instead of restart/mem_limit/cpus, image references instead of build,
removed depends_on). Web service uses start-first rolling updates;
workers use stop-first. Add deploy.sh script and GitHub Actions workflow
that auto-deploys on push to main via SSH.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+85 -38
+21
.github/workflows/deploy.yml
··· 1 + name: Deploy 2 + 3 + on: 4 + push: 5 + branches: [main] 6 + 7 + concurrency: 8 + group: deploy 9 + cancel-in-progress: false 10 + 11 + jobs: 12 + deploy: 13 + runs-on: ubuntu-latest 14 + steps: 15 + - name: Deploy via SSH 16 + uses: appleboy/ssh-action@v1 17 + with: 18 + host: ${{ secrets.DEPLOY_HOST }} 19 + username: ${{ secrets.DEPLOY_USER }} 20 + key: ${{ secrets.DEPLOY_SSH_KEY }} 21 + script: cd ${{ secrets.DEPLOY_PATH }} && ./deploy.sh
+16
deploy.sh
··· 1 + #!/usr/bin/env bash 2 + set -euo pipefail 3 + 4 + cd "$(dirname "$0")" 5 + 6 + echo "Pulling latest code..." 7 + git pull origin main 8 + 9 + echo "Building image..." 10 + docker build -t favs-blue:latest . 11 + 12 + echo "Deploying stack..." 13 + docker stack deploy -c docker-compose.yml favs-blue 14 + 15 + echo "Deploy complete. Watching service updates..." 16 + docker stack services favs-blue
+48 -38
docker-compose.yml
··· 25 25 services: 26 26 clickhouse: 27 27 image: clickhouse/clickhouse-server:26.2 28 - restart: unless-stopped 29 28 ports: 30 29 - "8123:8123" 31 30 volumes: ··· 34 33 CLICKHOUSE_DB: favs 35 34 CLICKHOUSE_USER: favs 36 35 CLICKHOUSE_PASSWORD: ${CLICKHOUSE_PASSWORD} 37 - ulimits: 38 - nofile: 262144 39 - mem_limit: 4g 40 - cpus: 2 36 + deploy: 37 + restart_policy: 38 + condition: any 39 + resources: 40 + limits: 41 + memory: 4G 42 + cpus: "2" 41 43 logging: *default-logging 42 44 healthcheck: 43 45 test: ["CMD", "wget", "-qO-", "http://localhost:8123/ping"] ··· 47 49 start_period: 5s 48 50 49 51 migrate: 50 - build: . 52 + image: favs-blue:latest 51 53 command: sh -c "node ace.js migration:run --force && node ace.js clickhouse:migrate" 52 - depends_on: 53 - clickhouse: 54 - condition: service_healthy 55 54 volumes: 56 55 - sqlite-data:/data 57 - mem_limit: 512m 58 - cpus: 0.5 56 + deploy: 57 + restart_policy: 58 + condition: on-failure 59 + resources: 60 + limits: 61 + memory: 512M 62 + cpus: "0.5" 59 63 logging: *default-logging 60 64 environment: 61 65 <<: *common-env ··· 63 67 OTEL_EXPORTER_OTLP_HEADERS: "" 64 68 65 69 web: 66 - restart: unless-stopped 67 - build: . 70 + image: favs-blue:latest 68 71 command: node bin/server.js 69 - depends_on: 70 - clickhouse: 71 - condition: service_healthy 72 - migrate: 73 - condition: service_completed_successfully 74 72 volumes: 75 73 - sqlite-data:/data 76 - mem_limit: 1536m 77 - cpus: 1 74 + deploy: 75 + restart_policy: 76 + condition: any 77 + update_config: 78 + order: start-first 79 + failure_action: rollback 80 + resources: 81 + limits: 82 + memory: 1536M 83 + cpus: "1" 78 84 logging: *default-logging 79 85 environment: 80 86 <<: *common-env ··· 92 98 start_period: 10s 93 99 94 100 jetstream-worker: 95 - restart: unless-stopped 96 - build: . 101 + image: favs-blue:latest 97 102 command: node ace.js jetstream:consume 98 103 stop_grace_period: 30s 99 - depends_on: 100 - clickhouse: 101 - condition: service_started 102 - migrate: 103 - condition: service_completed_successfully 104 104 volumes: 105 105 - sqlite-data:/data 106 - mem_limit: 512m 107 - cpus: 0.5 106 + deploy: 107 + restart_policy: 108 + condition: any 109 + update_config: 110 + order: stop-first 111 + failure_action: rollback 112 + resources: 113 + limits: 114 + memory: 512M 115 + cpus: "0.5" 108 116 logging: *default-logging 109 117 healthcheck: 110 118 test: ["CMD", "node", "-e", "process.exit(0)"] ··· 118 126 OTEL_SERVICE_NAME: favs-blue-jetstream 119 127 120 128 queue-worker: 121 - restart: unless-stopped 122 - build: . 129 + image: favs-blue:latest 123 130 command: node ace.js queue:work 124 - depends_on: 125 - clickhouse: 126 - condition: service_started 127 - migrate: 128 - condition: service_completed_successfully 129 131 volumes: 130 132 - sqlite-data:/data 131 - mem_limit: 1g 132 - cpus: 0.5 133 + deploy: 134 + restart_policy: 135 + condition: any 136 + update_config: 137 + order: stop-first 138 + failure_action: rollback 139 + resources: 140 + limits: 141 + memory: 1G 142 + cpus: "0.5" 133 143 logging: *default-logging 134 144 healthcheck: 135 145 test: ["CMD", "node", "-e", "process.exit(0)"]