Deployment Process¶
Three environments¶
| Environment | Branch | VPS path | DB suffix |
|---|---|---|---|
| development | develop |
local Docker | _dev |
| staging | staging |
/opt/dev/<project>/ |
_staging |
| production | main |
/opt/prod/<project>/ |
_prod |
Branch discipline¶
- Never commit directly to
mainorstaging - Hotfix path is the only exception, and it must be back-merged to
developthe same day - Merge requests in Forgejo require at least one approval
Promotion rules¶
- Develop → staging: automatic on push if CI passes
- Staging → production: manual, with explicit approval from João. Never automated. Never inferred. Never assumed.
Per-project deployment shape¶
Most projects share this shape:
- Build container image (tagged with the git SHA and the semver from
VERSION) - Push image to the Forgejo container registry
- SSH to VPS,
cd /opt/prod/<project>/,docker compose pull && docker compose up -d - Confirm healthcheck passes via
docker ps - Tag the git commit
v<MAJOR>.<MINOR>.<PATCH> - Update
CHANGELOG.md(auto viagit-cliff, then human review)
Version policy¶
VERSIONfile at the root of every project- Semver:
MAJOR.MINOR.PATCH - API responses include
X-App-Versionheader - A version badge is rendered bottom-left of every page, invisible until hover
Rollback¶
For container-based services:
docker compose stop <service>
docker tag <image>:v<old> <image>:rollback
docker compose up -d <service>
For schema changes that broke things: the Alembic down() migration must work. If it does not work, that is the bug to fix, not the deployment.
What is special about the JB stack¶
- No CI/CD provider. Build happens locally or on the VPS. There is no GitHub Actions because there is no GitHub.
- Forgejo Actions is available but not currently used — tracked for future.
jb-skills-gatewaycan be redeployed without restarting individual skills — they live-reload from filesystem.