Skip to content

Deployment & CI/CD

keepcadence deploys with trunk-based development + build-once image promotion. There are no long-lived environment branches.

feature/* ──PR──▶ main
push to main ───┼──▶ CI (check + python) .github/workflows/ci.yml
└──▶ Release: build sha-<SHA> .github/workflows/release.yml
images → ghcr.io/schneid-l/*
└──▶ auto-deploy STAGING
git tag vX.Y.Z ──▶ promote: retag sha-<SHA> → vX.Y.Z + latest (no rebuild)
└──▶ deploy PRODUCTION

The image tested on staging is the exact same digest promoted to production — promote only retags, it never rebuilds.

Merge a PR into main (or push to main). That’s it:

  1. ci.yml runs check (lint, types, build, unit tests) + python (worker pytest). e2e runs on PRs and nightly only — not on every push (private-repo Actions minutes are metered).
  2. release.yml builds the six app images tagged sha-<commit>, cosign-signs them, attaches an SBOM, pushes to GHCR, then triggers the Coolify staging deploy for all six apps.

Staging URLs: see runbooks/coolify.md. Health: curl https://api.staging.keepcadence.stream/health/ping.

Production deploys are gated — only a version tag can trigger one:

Terminal window
git tag v1.4.0 && git push origin v1.4.0

This runs promote (retags the already-built sha-<commit> images to v1.4.0 + latest) then deploy-production. The production GitHub Environment restricts deployments to v* tags.

Rollback = deploy an earlier tag’s image (re-run deploy-production for the previous v*, or point Coolify at the older image).

turbo build/test/check-types hit a self-hosted Turborepo remote cache at https://turbo-cache.host.schne.id (a container in the keepcadence-infra Coolify project). An unchanged push is a near-total cache hit. TURBO_TOKEN/TURBO_TEAM are the repo secret/variable.

  • Image builds never cancel (a half-pushed layer is corrupt).
  • Staging deploys cancel superseded runs — newest commit wins.
  • Production deploys never cancel — a tag promotion must complete.
PieceWhere
Apps (6)Coolify project keepcadence, staging environment
DBCoolify-managed Postgres (pgvector); daily backup → R2
Shared infraCoolify project keepcadence-infra — Actions runner, turbo cache
Worker GPUsRunPod serverless, 9 endpoints
TLSTraefik + Let’s Encrypt (letsencryptkc HTTP-01 resolver)
AnalyticsPostHog proxy at users.keepcadence.stream

Repo: COOLIFY_DEPLOY_TOKEN, COOLIFY_WEBHOOK_{API,ORCHESTRATOR,APP,ADMIN,LANDING,DOCS}, TURBO_TOKEN, KC_CF_API_TOKEN, KC_CF_ACCOUNT_ID, KC_STAGING_PG_PASSWORD. Repo vars: COOLIFY_API_URL, TURBO_TEAM. Environments: staging (no gate), production (v* tags only).