feat(nix): default container.defaultImage to a digest-pinned buildpack-deps:stable-scm #231

Merged
dominik.polakovics merged 1 commit from afk/230 into main 2026-07-25 17:09:36 +02:00

Closes #230

A stock module deployment refused every container spawn for repos without their own image_ref ("no dev image for this repo …") because container.defaultImage defaulted to null and the production host config never set it. The module now ships a working default; ADR-0053's demotion stands (explicit null opt-out valid, per-repo image_ref wins), and the Go binary's --container-image default stays empty.

What changed

  • nix/module.nixcontainer.defaultImage defaults to docker.io/library/buildpack-deps:stable-scm@sha256:07554a82a7a29ce00a048e0b29d18f454b5721b41940d43ee3be1ef59d55b114 (digest resolved at implementation time; tag kept for readability). The manual re-pin command sits in a comment beside the literal. The debian:stable-slim example is gone — it never satisfied the dev-image contract.
  • flake.nix — checks flipped: the default unit must carry the exact pinned ref in ExecStart (eval assert on the option default + text-level grep); a renamed containerNullImageDummy sets defaultImage = null; explicitly and proves the opt-out renders no --container-image; the explicit debian:stable-slim override fixture now also proves a set value replaces the default (negative grep on buildpack-deps).
  • .forgejo/workflows/deploy.yml — the skopeo "wait for refs" step also probes the default dev-image ref, extracted from nix/module.nix (fails loudly unless exactly one docker.io digest literal matches, so a re-pin PR updates the probe for free). This knowingly adds docker.io to the deploy path's probe dependencies.
  • docs/ops.md — module-table row, container-runner prose, opt-out example, and the "Dev image expectations" contradiction fixed: buildpack-deps:stable-scm qualifies as-is, alpine only with git+openssh-client added, plain debian:stable-slim does not qualify.
  • docs/adr/0056 — short successor ADR to ADR-0053 (which gets a superseded-in-part note): the demotion stands; only the module default moves from null to the pinned stock scm image.

Verification

  • nix flake check passes locally ("all checks passed!"), including the flipped nixos-module assertions and the container closure build.
  • Default unit renders --container-image docker.io/library/buildpack-deps:stable-scm@sha256:07554a82… in ExecStart; explicit defaultImage = null renders none (both now pinned by eval asserts + text-level greps).
  • Deploy-step script: bash -n clean, YAML parses, and the ref-extraction guard was smoke-tested against zero-, one-, and two-match inputs.

🤖 Generated with Claude Code

Closes #230 A stock module deployment refused every container spawn for repos without their own `image_ref` ("no dev image for this repo …") because `container.defaultImage` defaulted to `null` and the production host config never set it. The module now ships a working default; ADR-0053's demotion stands (explicit `null` opt-out valid, per-repo `image_ref` wins), and the Go binary's `--container-image` default stays empty. ## What changed - **nix/module.nix** — `container.defaultImage` defaults to `docker.io/library/buildpack-deps:stable-scm@sha256:07554a82a7a29ce00a048e0b29d18f454b5721b41940d43ee3be1ef59d55b114` (digest resolved at implementation time; tag kept for readability). The manual re-pin command sits in a comment beside the literal. The `debian:stable-slim` example is gone — it never satisfied the dev-image contract. - **flake.nix** — checks flipped: the default unit must carry the exact pinned ref in ExecStart (eval assert on the option default + text-level grep); a renamed `containerNullImageDummy` sets `defaultImage = null;` explicitly and proves the opt-out renders no `--container-image`; the explicit `debian:stable-slim` override fixture now also proves a set value replaces the default (negative grep on `buildpack-deps`). - **.forgejo/workflows/deploy.yml** — the skopeo "wait for refs" step also probes the default dev-image ref, extracted from `nix/module.nix` (fails loudly unless exactly one docker.io digest literal matches, so a re-pin PR updates the probe for free). This knowingly adds docker.io to the deploy path's probe dependencies. - **docs/ops.md** — module-table row, container-runner prose, opt-out example, and the "Dev image expectations" contradiction fixed: `buildpack-deps:stable-scm` qualifies as-is, `alpine` only with `git`+`openssh-client` added, plain `debian:stable-slim` does not qualify. - **docs/adr/0056** — short successor ADR to ADR-0053 (which gets a superseded-in-part note): the demotion stands; only the module default moves from `null` to the pinned stock scm image. ## Verification - `nix flake check` passes locally ("all checks passed!"), including the flipped `nixos-module` assertions and the container closure build. - Default unit renders `--container-image docker.io/library/buildpack-deps:stable-scm@sha256:07554a82…` in ExecStart; explicit `defaultImage = null` renders none (both now pinned by eval asserts + text-level greps). - Deploy-step script: `bash -n` clean, YAML parses, and the ref-extraction guard was smoke-tested against zero-, one-, and two-match inputs. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(nix): default container.defaultImage to digest-pinned buildpack-deps:stable-scm (issue #230)
All checks were successful
ci / native (pull_request) Successful in 8m35s
ci-nix / flake-check (pull_request) Successful in 23m27s
46fa9f50cd
A stock module deployment refused every container spawn for repos
without their own image_ref because container.defaultImage defaulted to
null. The module now ships a working, digest-pinned default —
docker.io/library/buildpack-deps:stable-scm@sha256:07554a82… — which
satisfies the dev-image contract as-is; the Go binary's
--container-image default stays empty (the module is the opinionated
deployment layer, as with toolsImages / ADR-0054).

- nix/module.nix: pinned default with the manual re-pin command beside
  the literal; explicit null stays a valid opt-out (ADR-0053).
- flake.nix: default unit must carry the pinned ref; explicit-null
  fixture proves the opt-out renders no --container-image; the explicit
  debian:stable-slim override fixture proves a set value replaces (not
  joins) the default.
- deploy.yml: the skopeo wait step also probes the dev-image ref,
  extracted from nix/module.nix (exactly-one guard), knowingly adding
  docker.io to the deploy probe dependencies.
- docs/ops.md: module table, container-runner prose, and the dev-image
  contract examples (buildpack-deps:stable-scm qualifies as-is;
  debian:stable-slim never did).
- docs/adr/0056: successor ADR; ADR-0053 marked superseded in part.

Closes #230

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Author
Owner

[autoland] verdict: pass

Clean PASS. CI aggregate success (ci/native + ci-nix/flake-check both green; flake-check exercised the flipped nixos-module assertions and container closure build for this diff). Conventional Commits title, working Closes #230, diff-scope matches issue #230's five work items exactly with no drive-by changes. Deploy probe's grep resolves to exactly one docker.io digest literal in nix/module.nix; digest consistent across module.nix, flake.nix, ops.md, ADR-0056.

[autoland] verdict: pass Clean PASS. CI aggregate success (ci/native + ci-nix/flake-check both green; flake-check exercised the flipped nixos-module assertions and container closure build for this diff). Conventional Commits title, working Closes #230, diff-scope matches issue #230's five work items exactly with no drive-by changes. Deploy probe's grep resolves to exactly one docker.io digest literal in nix/module.nix; digest consistent across module.nix, flake.nix, ops.md, ADR-0056.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Cloonar/coding-lab!231
No description provided.