Advanced

Deployment Guardrails

CI checks, protected deploy workflow, production approval, and explicit deploy consent.

Production, staging, and feature-preview deploys run through GitHub Actions in .github/workflows/deploy.yml. The operational deploy sequence is also summarized in Deploy.

Required checks#

Every pull request and branch push runs the CI workflow:

pnpm lint
pnpm build

The Deploy workflow repeats the same lint and build steps in a verify job. Production, staging, and preview deploy jobs all depend on that job, so a deploy cannot start until the current ref builds cleanly.

Recommended repository settings:

  1. In Settings > Branches, require the CI / Lint and build status check before merging to the protected branch.
  2. In Settings > Environments, create staging and production environments.
  3. Create a preview environment if you want separate preview secrets or approvals.
  4. Store deploy secrets in the relevant GitHub environments.

Production deploys#

Pushes to origin/main or origin/master deploy production automatically after lint and build pass.

Production deploys publish all three production Fly apps:

  • fly.worker.toml -> chat-dev-worker
  • fly.server.toml -> chat-dev-server
  • fly.web.toml -> chat-dev-web

When the worker component deploys, the workflow stages the new FLY_WORKER_IMAGE on chat-dev-server and deploys the server so new Machines use the new worker image.

Manual production deploys are still available from the GitHub Deploy workflow with:

  • environment: production
  • components: all, worker, server, or web

Staging deploys#

Pushes to origin/staging deploy staging automatically after lint and build pass.

Staging deploys publish all three staging Fly apps:

  • fly.worker-dev.toml -> chat-dev-worker-dev
  • fly.server-dev.toml -> chat-dev-server-dev
  • fly.web-dev.toml -> chat-dev-web-dev

Manual staging deploys are also available from the GitHub Deploy workflow with:

  • environment: staging
  • components: all, worker, server, or web

If the worker image changes, the workflow stages FLY_WORKER_IMAGE on the staging server. Deploying the server in the same run applies the new image to new machines.

Feature preview deploys#

Pushes to origin/feature/<slug> or origin/features/<slug> create or update isolated Fly preview apps after lint and build pass. For a branch named feature/addabutton or features/addabutton, the workflow creates:

  • addabutton-chat-dev-worker-dev
  • addabutton-chat-dev-server-dev
  • addabutton-chat-dev-web-dev

The preview web URL is:

https://addabutton-chat-dev-web-dev.fly.dev

The preview API URL is:

https://addabutton-chat-dev-server-dev.fly.dev

Each preview server gets its own chat_dev_data_dev Fly volume on that preview app, so the SQLite database is isolated from staging and production. The workflow wires the preview server to the preview worker app with FLY_WORKER_APP, FLY_WORKER_IMAGE, and WORKER_CALLBACK_URL.

Preview apps use the slugged Fly app hostname rather than addabutton.chat-dev-web-dev.fly.dev; the latter would require a wildcard custom domain in Fly/DNS.

GitHub secret setup#

Set these GitHub environment or repository secrets:

SecretRequiredPurpose
FLY_API_TOKENYesFly deploy authentication and server-side worker Machine creation.
WORKER_SECRETRecommendedShared server/worker callback secret for preview apps.
CHAT_DEV_ENCRYPTION_KEYRecommendedEncryption key for preview app stored credentials.

Local production deploy#

Do not run direct production fly deploy -c fly.*.toml commands as a normal workflow. Use CI/CD.

If GitHub Actions is unavailable and the user has explicitly said deploy to prod or push to prod in the current task, follow the manual production sequence in Deploy.

Staging analytics#

Staging web builds set NEXT_PUBLIC_ENABLE_MIXPANEL=0 in fly.web-dev.toml. Production leaves Mixpanel enabled by default. When testing locally, use the same flag to verify the staging bundle does not inject Mixpanel:

NEXT_PUBLIC_ENABLE_MIXPANEL=0 pnpm --filter web build