CI/CD
Two distinct pipelines: service images (build → registry → Flux) and docs sites (build → Cloudflare Pages).
Service image builds
Each Node service has a buildspec.yml (AWS CodeBuild). The shared shape:
1. ECR/ACR login
2. docker build (from the service Dockerfile)
3. tag + push to the registry
4. post-build: kubectl rollout restart (where applicable)
From there, FluxCD's image automation takes over — see
Deployment & GitOps. The registry is
Azure ACR (knockknockacr.azurecr.io) for Flux-tracked tags; some specs also push
to AWS ECR.
Dockerfiles are multi-stage and run as non-root on Node 22 Alpine:
| Service | Notable build detail |
|---|---|
| backend | Node 22 + FFmpeg, 6 GB heap, port 8888 |
| ms-ai | 3-stage (deps → build → runtime); migrations run in CI, not entrypoint |
| ms-communication / ms-sessions | Node 22 Alpine; ms-sessions ships an HTTP image + a worker process |
| frontend / widget | multi-stage → nginx Alpine static serving |
| desktop | not containerized — electron-builder → GitHub releases |
There are also Dockerfile.azure / Dockerfile.stage variants per service for the
Azure and staging targets.
Desktop releases
desktop publishes via electron-builder → GitHub releases (publish /
publish:next for white-label), with delta updates consumed by electron-updater.
Not part of the Kubernetes pipeline.
Docs sites
Both docs-site and internal-docs deploy to Cloudflare Pages via GitHub
Actions on push to main:
# .github/workflows/deploy.yml
- npm ci
- npm run build
- wrangler pages deploy build --project-name=knock-knock-internal-docs
(Customer docs use --project-name=knock-knock-docs.) Requires the
CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID repo secrets.
Branch model
Service repos build from dev; flux-deployments and the docs sites track main.
Image automation bumps tags in flux-deployments automatically — those commits are
made by the Flux bot, not engineers.