Prove the Docker image runs: HEALTHCHECK instruction and a make docker-smoke target that starts the image and checks the healthcheck #111

Closed
opened 2026-09-21 09:19:49 +02:00 by clawbot · 2 comments
Collaborator

Verified against next at 2d80512.

Nothing in the repo proves the Docker image produces a running service. script/cibuild builds the image and stops; script/docker tags it and stops. A change that breaks startup (a bad ENTRYPOINT, a missing runtime library, a config the loader rejects) passes every gate and is discovered on the deploy host. The runtime stage also has no HEALTHCHECK, so the container runtime and upaas cannot tell a hung process from a healthy one.

Definition of done

  1. Dockerfile runtime stage gets a HEALTHCHECK probing http://localhost:8080/.well-known/healthcheck.json (busybox wget --spider is available on alpine; no new packages). Interval 30s, timeout 5s, start period 10s, retries 3.
  2. New script/docker-smoke (POSIX sh, set -eu, repo root located the standard way) and a make docker-smoke shim: builds the image via script/docker, starts a container with a throwaway PIXA_SIGNING_KEY and a random free host port, polls the healthcheck URL for up to 30 seconds, exits 0 only on an HTTP 200, and always stops and removes the container it started (trap on exit). It kills only the container it created, never anything selected by pattern.
  3. make docker-smoke is NOT part of make check (it needs a Docker daemon and minutes of build time). The Gitea workflow runs it after script/cibuild.
  4. README.md Entrypoints section lists the new script in one line.
  5. State in the PR body that make docker-smoke passed locally and that a deliberately broken ENTRYPOINT made it fail; no transcripts.

Constraints

  • Depends on #110 (the image must accept PIXA_SIGNING_KEY); start after it merges.
  • Touches Dockerfile (runtime stage only) and .gitea/workflows/check.yml, which #101 also edits; rebase onto current next before pushing.
  • No scripted edits, no 4-byte characters.

model: claude-fable-5

Verified against `next` at `2d80512`. Nothing in the repo proves the Docker image produces a running service. `script/cibuild` builds the image and stops; `script/docker` tags it and stops. A change that breaks startup (a bad `ENTRYPOINT`, a missing runtime library, a config the loader rejects) passes every gate and is discovered on the deploy host. The runtime stage also has no `HEALTHCHECK`, so the container runtime and upaas cannot tell a hung process from a healthy one. ## Definition of done 1. `Dockerfile` runtime stage gets a `HEALTHCHECK` probing `http://localhost:8080/.well-known/healthcheck.json` (busybox `wget --spider` is available on alpine; no new packages). Interval 30s, timeout 5s, start period 10s, retries 3. 2. New `script/docker-smoke` (POSIX sh, `set -eu`, repo root located the standard way) and a `make docker-smoke` shim: builds the image via `script/docker`, starts a container with a throwaway `PIXA_SIGNING_KEY` and a random free host port, polls the healthcheck URL for up to 30 seconds, exits 0 only on an HTTP 200, and always stops and removes the container it started (trap on exit). It kills only the container it created, never anything selected by pattern. 3. `make docker-smoke` is NOT part of `make check` (it needs a Docker daemon and minutes of build time). The Gitea workflow runs it after `script/cibuild`. 4. `README.md` Entrypoints section lists the new script in one line. 5. State in the PR body that `make docker-smoke` passed locally and that a deliberately broken `ENTRYPOINT` made it fail; no transcripts. ## Constraints - Depends on https://git.eeqj.de/sneak/pixa/issues/110 (the image must accept `PIXA_SIGNING_KEY`); start after it merges. - Touches `Dockerfile` (runtime stage only) and `.gitea/workflows/check.yml`, which https://git.eeqj.de/sneak/pixa/issues/101 also edits; rebase onto current `next` before pushing. - No scripted edits, no 4-byte characters. model: claude-fable-5
clawbot added this to the 1.0.0 milestone 2026-09-21 09:19:49 +02:00
Author
Collaborator

Plan:

  • Dockerfile runtime stage: the HEALTHCHECK as specified (busybox wget --spider on http://localhost:8080/.well-known/healthcheck.json, interval 30s, timeout 5s, start period 10s, retries 3).
  • New script/docker-smoke and make docker-smoke: builds via script/docker, creates a container with a random throwaway PIXA_SIGNING_KEY, starts it, and waits up to 30 seconds for Docker to report it healthy, which happens only when the image's own HEALTHCHECK gets a success from the healthcheck URL. The container is removed by its ID on exit; on failure its log is printed.
  • The Gitea workflow runs it after script/cibuild; one line in the README Entrypoints section; a TODO.md entry.

Judgement call: the check runs inside the container rather than polling a random host port from outside. The Gitea job itself runs in a container on its own Docker network (runner log of https://git.eeqj.de/sneak/pixa/actions/runs/6691), so a port the smoke container publishes on the host is not reachable from the job at localhost, and the workflow step from item 3 would always fail. Waiting on Docker's health status works on a laptop and on the runner, needs no free port, and also proves the new HEALTHCHECK line works. The script passes --health-interval=1s so the first probe does not wait the image's 30 seconds.

Model: opus-5-5

Plan: - `Dockerfile` runtime stage: the `HEALTHCHECK` as specified (busybox `wget --spider` on `http://localhost:8080/.well-known/healthcheck.json`, interval 30s, timeout 5s, start period 10s, retries 3). - New `script/docker-smoke` and `make docker-smoke`: builds via `script/docker`, creates a container with a random throwaway `PIXA_SIGNING_KEY`, starts it, and waits up to 30 seconds for Docker to report it healthy, which happens only when the image's own `HEALTHCHECK` gets a success from the healthcheck URL. The container is removed by its ID on exit; on failure its log is printed. - The Gitea workflow runs it after `script/cibuild`; one line in the README Entrypoints section; a `TODO.md` entry. Judgement call: the check runs inside the container rather than polling a random host port from outside. The Gitea job itself runs in a container on its own Docker network (runner log of https://git.eeqj.de/sneak/pixa/actions/runs/6691), so a port the smoke container publishes on the host is not reachable from the job at `localhost`, and the workflow step from item 3 would always fail. Waiting on Docker's health status works on a laptop and on the runner, needs no free port, and also proves the new `HEALTHCHECK` line works. The script passes `--health-interval=1s` so the first probe does not wait the image's 30 seconds. Model: opus-5-5
Author
Collaborator

Built as planned in the comment above: #130

Model: opus-5-5

Built as planned in the comment above: https://git.eeqj.de/sneak/pixa/pulls/130 Model: opus-5-5
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/pixa#111