Repository navigation
Deploy Cloud #92
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Deploy Cloud | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: "Docker image tag to deploy (default: latest)" | |
| required: false | |
| default: "latest" | |
| type: string | |
| jobs: | |
| deploy: | |
| name: Deploy to Cloud Droplet | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Copy config files to server | |
| uses: appleboy/scp-action@v1.0.0 | |
| with: | |
| host: ${{ secrets.CLOUD_HOST }} | |
| username: root | |
| key: ${{ secrets.CLOUD_SSH_KEY }} | |
| source: "docker-compose.cloud.yml,deploy/cloud/Caddyfile,deploy/cloud/db-rest/Dockerfile" | |
| target: /tmp/anythingmcp-deploy | |
| overwrite: true | |
| - name: Deploy via SSH | |
| uses: appleboy/ssh-action@v1 | |
| env: | |
| CRON_SECRET: ${{ secrets.ONBOARDING_CRON_SECRET }} | |
| with: | |
| host: ${{ secrets.CLOUD_HOST }} | |
| username: root | |
| key: ${{ secrets.CLOUD_SSH_KEY }} | |
| envs: CRON_SECRET | |
| script: | | |
| set -e | |
| cd /opt/anythingmcp-cloud | |
| # Pull the requested tag AND refresh :latest, since | |
| # docker-compose.cloud.yml references :latest. Without this | |
| # the local :latest tag can point to an older image. | |
| docker pull helpcodeai/anythingmcp:${{ inputs.tag }} | |
| docker pull helpcodeai/anythingmcp:latest | |
| # Update compose, Caddyfile and the custom db-rest Dockerfile from | |
| # checkout. The Dockerfile is the build context for the db-rest | |
| # service; `docker compose up` builds it if the pinned image tag is | |
| # missing (fresh droplet), otherwise the existing image is reused. | |
| cp /tmp/anythingmcp-deploy/docker-compose.cloud.yml ./docker-compose.cloud.yml | |
| cp /tmp/anythingmcp-deploy/deploy/cloud/Caddyfile ./Caddyfile | |
| mkdir -p ./deploy/cloud/db-rest | |
| cp /tmp/anythingmcp-deploy/deploy/cloud/db-rest/Dockerfile ./deploy/cloud/db-rest/Dockerfile | |
| rm -rf /tmp/anythingmcp-deploy | |
| # Keep CRON_SECRET in the server .env in sync with the repo | |
| # secret so the onboarding-reminders cron can authenticate. | |
| # Upsert (replace-or-append) without disturbing other vars. | |
| touch .env | |
| if grep -q '^CRON_SECRET=' .env; then | |
| sed -i "s#^CRON_SECRET=.*#CRON_SECRET=${CRON_SECRET}#" .env | |
| else | |
| echo "CRON_SECRET=${CRON_SECRET}" >> .env | |
| fi | |
| # Recreate ONLY the app to pick up the new image/config (postgres, | |
| # redis and db-rest keep running — no data churn, no needless | |
| # downtime), and wait until it reports healthy. The old command | |
| # force-recreated the whole stack with no health gate, so a | |
| # crash-on-start went unnoticed and could take the DB down with it. | |
| docker compose -f docker-compose.cloud.yml up -d \ | |
| --no-deps --force-recreate --wait --wait-timeout 300 app | |
| # Ensure the proxy + any other services are up (caddy waits for the | |
| # app to be healthy, which it now is). | |
| docker compose -f docker-compose.cloud.yml up -d --remove-orphans | |
| docker image prune -f | |
| echo "Deployment complete" |