Build & Deploy
CI — Bitbucket Pipelines
- Feature /
developpushes → tests + lint (+ a web preview where applicable). - A SemVer tag →
assemble.shbuilds and pushesclustersco/<app>:<ver>to Docker Hub (:latestmoves only for a final release, never a pre-release). - Version tags are immutable — never re-push a tag; the image,
version.yml, and tag must agree. - Enforce in CI what Bitbucket can't gate as a branch rule (e.g. "branch up to date", "linked Jira in status") as a required pipeline step.
Runtime — Docker Swarm
docker-stack.yml with deploy: → replicas, rolling update_config (order: start-first),
rollback_config (order: stop-first), restart_policy: on-failure. App serves on port 80.
- DB: MySQL 8.0. Persistent volumes:
uploads,media,backups,temp. - Config & secrets: env vars (
APP_ENV,APP_BASE_URL,DB_*,CLIENT) from.conf/.conf.example. Secrets come from a runtime secret store — never committed, never baked into the image. Gate PRs withgitleaks. - Portability: images stay deployable to plain Apache/Nginx; Kubernetes is a future target.
Environments & promotion
A tag builds one image; that exact @sha256 digest is promoted across environments —
build once, promote the digest, never rebuild per environment.
| Environment | Gets | Gate in |
|---|---|---|
| Development | every tag, automatically | none — auto; smoke + migration checks |
| Staging | the same digest, promoted from Dev | green Dev checks |
| Production | the same digest, promoted from Staging | manual approval after UAT |
| Beta | pre-release (-beta.N) tags only | off the main path |
Model these as Bitbucket Deployments environments so every promotion is recorded and prod carries
a required approval. Roll out start-first; roll back to the last-good digest stop-first.
:::tip What makes rollback safe Keep every migration backward-compatible (expand/contract) — add the new shape in one release and only drop the old shape a release later, never both at once. Then "redeploy the previous digest" is always safe one version back. :::
The interactive Deploy & promote view in the Git & Versioning Workflow walks all four paths (release, beta, hotfix, rollback).
cluster-cli (tooling exception)
Apps ship as Docker images; the cluster-cli is a Go binary. Same workflow + tag-as-release rule,
different artifact: a SemVer tag runs build.sh, which cross-compiles every platform and uploads
archives + checksums.txt + latest.txt + installers to a Cloudflare R2 bucket
(get.clustersco.com, behind Cloudflare Access).