The policy accepted only `staging` as a head for main, so any change production needed before the next promotion had nowhere to go: the PR was unmergeable by CI and branch protection blocks direct pushes. Accept `hotfix/*` and `release/*` heads as well. The naming requirement keeps a direct-to-main change deliberate and visible, and the master freeze plus the "features target staging" rule are unchanged. Document the escape hatch and the need to land the same commit on staging. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2.5 KiB
Backend deployment and branching
Dokploy deploys the standalone backend directly from GitHub. GitHub Actions is the verification gate; it does not hold a broad Dokploy API credential and does not deploy the retired Supabase data plane.
Branch contract
| Branch | Purpose | Dokploy target | Public API |
|---|---|---|---|
| feature branches | isolated reviewed work | none | none |
staging |
integrated release candidate | backend-staging |
https://api.preprod.sauci.app |
main |
production promotion | backend-production |
https://api.sauci.app |
master |
frozen legacy default | none | none |
Normal feature pull requests target staging. After CI and authenticated staging
acceptance pass, open a promotion pull request from staging to main. Prefer
that route: production then runs the exact commit already exercised in staging.
When production needs a change that cannot wait for the next promotion, open a
pull request into main from a hotfix/* or release/* branch. CI enforces
that naming so a direct-to-main change is always deliberate and visible. Land
the same commit on staging too, or the next promotion will revert it. Direct
pushes to either deployment branch remain blocked by branch protection.
Each Dokploy Compose application is connected to jjbrunton/Sauci, watches its
single branch with push-triggered automatic deployment, and uses
infra/backend/compose.production.yaml. The Compose file deliberately has no
top-level project name so Dokploy assigns different project names, networks, and
named volumes to staging and production. Never point both applications at the
same PostgreSQL or media volume.
Promotion checks
- GitHub
Verify / staticandVerify / backend-integrationsucceed for the candidate commit. - The Dokploy deployment for
stagingreports success;/health/liveand/health/readyreturn 200 over valid TLS. - An unauthenticated protected request returns 401, proving the public route is not bypassing authentication.
- The mobile app signs in through non-production Supabase Auth and reads real
migrated content from
https://api.preprod.sauci.app. - Promote the exact
stagingcommit tomainand verify the production health, TLS, and authentication boundary independently.
Health proves infrastructure, not customer-data cutover. The App Store build must not be released against production until the controlled final sync and the checks in backend-cutover.md are complete.