Chapter 12: Deployment¶
Audience: DevOps, platform engineers
CI/CD pipeline¶
Push to unified-platform
│
▼
build-and-push.yml (automatic)
├── Run contract & recovery tests
├── Build API image
├── Build Dashboard image
└── Push to Artifact Registry
│
▼ (manual trigger)
deploy.yml (workflow_dispatch)
├── SSH into VM via IAP tunnel
├── git pull on VM
├── docker compose pull (prebuilt images)
├── docker compose up -d --force-recreate
├── Health check (60s wait + curl localhost:8000/health)
└── Post-deploy contract check
Why deploy is manual¶
Auto-deploy on push was disabled after a January 2026 incident where automatic deploys competed with manual SSH deployments, corrupting containers and causing data loss. The deploy workflow now requires:
- Manual trigger via GitHub Actions UI ("Run workflow")
- Explicit target selection (staging or production)
- Typing
DEPLOYas confirmation - Optional reason field for audit trail
Image tags¶
Images are tagged with the short git SHA: sha-XXXXXXX. The deploy step
uses GITHUB_SHA to construct the tag, so the deployed version always maps
to a specific commit.
How to deploy¶
- Verify the build passed:
gh run list --workflow=build-and-push.yml --limit=1 - Trigger deploy:
gh workflow run deploy.yml \ --ref unified-platform \ -f target=production \ -f confirm=DEPLOY \ -f reason="your reason here" - Monitor:
gh run watch <run_id> --exit-status - Verify:
curl -sS https://scan.rtb.cat/api/health | jq -r '.git_sha,.version'
Verifying a deploy¶
The /api/health endpoint returns:
{
"git_sha": "94e9cbb0",
"version": "sha-94e9cbb"
}
Compare git_sha against the commit you intended to deploy.
Post-deploy contract check¶
After deployment, the workflow runs scripts/contracts_check.py inside the
API container. This validates that data contracts (non-negotiable rules from
import through API output) are holding. If the check fails:
- With
ALLOW_CONTRACT_FAILURE=false(default): deploy is marked as failed. - With
ALLOW_CONTRACT_FAILURE=true(temporary bypass): deploy succeeds with a warning. This bypass must be removed after investigation.
Staging vs. production¶
| Environment | VM name | Domain |
|---|---|---|
| Staging | catscan-production-sg2 |
(internal) |
| Production | catscan-production-sg |
scan.rtb.cat |
Deploy to staging first, verify, then deploy to production.
Rollback¶
To roll back, deploy a previous known-good commit:
- Identify the last good SHA from git log or previous deploy runs.
- Check out that SHA on unified-platform (or use
--refwith the commit). - Trigger the deploy workflow.
There is no dedicated rollback mechanism. It's just deploying an older version.
Related¶
- Architecture Overview: what gets deployed
- Health Monitoring: verifying the deploy worked