Files
HealthLog/docs/audit/v1416-auto-deploy-fix.md
T
Marc-André BombeckandClaude Opus 4.7 a1cf9bcb37 docs: scrub PII + internal jargon + German leaks from user-facing artifacts
Retroactive cleanup of CHANGELOG.md and docs/audit/v1.4.X-summary.md
files. Removes maintainer's real name, specific health figures tied to
the live tenant, internal release-process jargon, and stray German
strings in English-only release notes. Pre-release PII-grep gate added
to the v1.4.20 release pipeline. No git history rewrite.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 15:14:28 +02:00

5.9 KiB

v1.4.16 — Auto-deploy follow-up (image-digest only)

Stage: Cleanup-C / item 4 Last updated: 2026-05-09 (v1.4.16 release cycle) Status: designed, not shipped — DEFERRED to v1.5 (manual maintainer step required; MCP API does not expose the toggle)

Background — what v1.4.15 left half-finished

The v1.4.15 C2 work (docs/audit/v1415-auto-deploy.md) wired the publish workflow to call Coolify's deploy webhook AFTER GHCR pushes the new image. That solves the "deploy fires when there is a new image" half correctly.

What it did NOT solve: the Coolify application is configured with the GitHub-App integration (source_type: App\Models\GithubApp, git_repository: MBombeck/HealthLog, git_branch: main). Coolify's GitHub App auto-deploy fires on EVERY push to main — including .planning/, docs/, CHANGELOG.md, README.md and other doc-only commits that change zero image bytes. The compose pulls ghcr.io/mbombeck/healthlog:latest, finds the same digest, but still recreates the containers (Coolify always restarts the stack on a deploy event). During the v1.4.15 release cycle, user-observed container churn was reported — multi-second downtime windows on every doc-only push.

We need: deploy fires only when the image digest actually changes.

Investigation — what Coolify v4 supports

Coolify v4.0.0-beta.470 (current production) exposes these deploy-trigger toggles on a dockercompose application:

Setting Effect API access
Auto Deploy GitHub-App webhook listens to push events UI only (no MCP / REST endpoint exposes it on v4-beta)
Watch Paths Glob list — push-event paths must match for auto-deploy to fire UI only
Deploy Webhook Bearer-protected GET /api/v1/deploy?uuid=… — programmatic trigger MCP-callable
Notification Webhook Outgoing POST when deploy completes (success / failure) UI only

The MCP application.update action exposed by coolify-apps01 intentionally restricts mutations to the safe subset (fqdn, health_check_*, domains, name, description, environment_*, instant_deploy, build-pack family). It does NOT expose auto_deploy_enabled or watch_paths. Calling the bare REST API would require a Coolify UI-issued token AND would bypass the guardrails the MCP wraps around the install — too far outside the automated tooling's scope.

The Coolify community has an open feature request to expose auto_deploy_enabled over REST; the v4-stable line (expected July 2026) is the realistic landing window.

Watchtower — re-examined

v1415-auto-deploy.md rejected Watchtower for v1.4.15 ("polling daemon is material TCB expansion"). Re-examined here:

  • The dockercompose build_pack on Coolify v4 ships a restart: unless-stopped policy already; adding a Watchtower sidecar with --label-enable and a per-image com.centurylinklabs.watchtower.enable=true label on the app service would re-pull on registry-digest change with NO push-event traffic.
  • But a Watchtower install on apps-01 would also need read access to GHCR (private images) and sit in the same docker network as every other app on the host. That's a larger blast radius than the surgical "flip one Coolify toggle" alternative below.

Chosen approach — DEFER to v1.5 with concrete plan

v1.5 plan (concrete, two-step):

Step 1 — Maintainer-side manual toggle (5 min, before v1.5 cut)

Open Coolify UI → Applications > m-bombeck/-health-log:main-pg8wggwogo8c4gc4ks0kk4ss > Configuration:

  1. General → Auto Deploy: turn OFF.
  2. (Optional) General → Watch Paths: leave empty — the toggle above is enough; watch_paths only matters with Auto Deploy ON.
  3. Save.

Effect: GitHub-App push events from main no longer fire a Coolify deploy. The Actions-driven Trigger Coolify deploy step in docker-publish.yml (already shipped in v1.4.15) becomes the SOLE trigger — and it only fires AFTER the image actually pushes to GHCR. Doc-only commits never reach the deploy queue.

Step 2 — automate the toggle for v1.5+

When Coolify v4-stable lands (or once coolify-apps01 MCP gains the auto_deploy_enabled field), patch scripts/configure-coolify-app.ts to flip the toggle programmatically. Until then the manual UI step is the contract.

Why NOT Watchtower for v1.4.16

The maintainer's instruction was explicit: "Don't half-ship". Watchtower would ship code (a new container in the prod compose, new credentials to manage) for a problem the manual Coolify toggle solves with zero new moving parts. The right call is the toggle.

Test plan after the toggle flip

  1. Push a doc-only commit to main (e.g. amend CHANGELOG.md wording).
  2. Watch Coolify's deployment history for pg8wggwogo8c4gc4ks0kk4ss — there should be NO deploy entry for that SHA.
  3. Watch GHCR — no new image should be published either (the docker-publish.yml workflow only runs pnpm exec docker buildx when source changes, but we haven't path-filtered it yet — that's a separate v1.5 task).
  4. Tag a real release (e.g. v1.5.0) — the workflow runs, GHCR publishes, and the Trigger Coolify deploy step fires the webhook. Coolify deploys ONCE.

Status after this audit

  • v1.4.16: NO source change shipped for this item. The audit document is the deliverable.
  • Maintainer-side action: flip the Coolify toggle whenever convenient. Does not block v1.4.16 release.
  • v1.5 backlog: track the MCP-API automation as a concrete follow-up.