You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Deploy: gate production on a CI-built/tested image + readiness health-check + post-deploy smoke test #266
Deployment-readiness gap (#244), BLOCKER — flagged by 2 of 3 reviewers.
Problem
Nothing gates production on a tested artifact, and the deployment artifact is first
exercised at deploy time:
CI never builds the Docker image..github/workflows/ci.yml builds/tests
.NET and web source but never runs the multi-stage Dockerfile (npm ci, the web/dist→wwwroot copy, the sourcemap move). A Dockerfile break ships
undetected.
No container-level readiness wired. The app exposes /health/live (process)
and /health/ready (DB reachable + migrations applied)
(Program.cs:733-737), but
the compose app service has no healthcheck and the Dockerfile no HEALTHCHECK, so an instance whose /health/ready is 503 (DB down, migrations
pending) still looks up.
Fix
App-side / portable (this repo):
Add a docker build CI job: build the image, boot it against a throwaway
Postgres, hit /health/ready. Identify the artifact by immutable commit
SHA/digest.
Add a HEALTHCHECK to the Dockerfile (and a compose healthcheck) that probes /health/ready.
Provider-side (deployment repo):
The host's deploy manifest declares the readiness path (/health/ready) with a
timeout covering the boot migration.
Gate promotion on CI (required checks / "wait for CI") so a red run can't deploy.
Post-deploy smoke test through the production URL: /health/live, /health/ready, SPA loads, login, refresh cookie, one authenticated read.
Verify
Break the Dockerfile on a branch → CI fails. A 503-ready instance is not promoted.
Part of the #244 deployment-readiness audit; tracked in epic #15.
Re-scoping. The deploy-side of this issue moved to a separate deployment/ops repo (deploy manifest — migrate-before-serve, readiness gate, CI-gated immutable artifact — plus a post-deploy smoke test).
⬜ HEALTHCHECK — still open: no HEALTHCHECK in src/Cluckwork.Api/Dockerfile and no healthcheck on the compose app service (only db has one). Add both, probing /health/ready.
Keeping this open, now scoped to just that HEALTHCHECK task (a small app-side change); everything else here is either done (#294) or relocated to that deployment repo.
App-side landed in PR #304 (merged 2026-07-30): the runtime image + compose app service carry a HEALTHCHECK (an in-process healthcheck CLI verb probing /health/ready), a /health/{**rest} → 404 guard so the SPA fallback can't fake a green health check, and a CI image-job smoke that boots the built image against a throwaway Postgres and asserts /health/ready=200 + Docker health healthy + verb exit 0.
The remaining scope is host/deploy config, tracked in a separate deployment/ops repo:
deploy manifest: migrate-before-serve, readiness gate at /health/ready, CI-gated immutable artifact;
post-deploy smoke test through the production URL.
Closing here as a dup of that deploy-side work (same pattern as #260/#263); go-live tracking lives in that separate deployment repo.
Activity
chore(docker): image hardening — non-root user, pinned digests, Trivy…
mforce commentedon Jul 30, 2026
Re-scoping. The deploy-side of this issue moved to a separate deployment/ops repo (deploy manifest — migrate-before-serve, readiness gate, CI-gated immutable artifact — plus a post-deploy smoke test).
Of the app-side/portable half:
HEALTHCHECK— still open: noHEALTHCHECKinsrc/Cluckwork.Api/Dockerfileand nohealthcheckon the composeappservice (onlydbhas one). Add both, probing/health/ready.Keeping this open, now scoped to just that HEALTHCHECK task (a small app-side change); everything else here is either done (#294) or relocated to that deployment repo.
feat(api): container HEALTHCHECK via in-process `healthcheck` verb (#266
mforce commentedon Jul 30, 2026
App-side landed in PR #304 (merged 2026-07-30): the runtime image + compose
appservice carry aHEALTHCHECK(an in-processhealthcheckCLI verb probing /health/ready), a/health/{**rest}→ 404 guard so the SPA fallback can't fake a green health check, and a CIimage-job smoke that boots the built image against a throwaway Postgres and asserts /health/ready=200 + Docker healthhealthy+ verb exit 0.The remaining scope is host/deploy config, tracked in a separate deployment/ops repo:
Closing here as a dup of that deploy-side work (same pattern as #260/#263); go-live tracking lives in that separate deployment repo.
docs(agents): drop the private deploy repo's name from the host-agnos…
feat(web): serve a per-request CSP nonce so Emotion's styles apply un…