Opt-in Docker-in-Docker worker image + feature-based addon composition #56
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/dind"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #32.
Summary
Adds an opt-in Docker-in-Docker (dind) worker image (and a dind + Playwright combo) so agents can spin up disposable Docker stacks — smoke-test a
docker composechange, validate an image builds, or stand up a fresh Nexus and drive its UI with Playwright. Also lays a clean feature-dir addon layout and adocker-bake.hclbuild so future addons don't explode into 2^N image variants.Design/plan:
docs/superpowers/specs/2026-07-10-dind-worker-image-design.md·docs/superpowers/plans/2026-07-10-dind-worker-image.md.What's in it
nexus/src/lib/server/workers/capabilities.ts): labelorg.nexus.dind→HostConfigPrivileged: true,Init: true, and an anonymous/var/lib/dockervolume. Label-scoped, so privilege applies only to dind images the operator explicitly picks — that selection is the consent (single-operator model; no separate gate). Composes additively with the playwright capability for the combo image. Unit-tested.worker/addons/<name>/): each addon owns its build-timeinstall.shand any boot drop-in. The existing Playwright install was migrated into this layout.worker/Dockerfilegainsdind(FROM base) anddind-playwright(FROM playwright) stages that share one dind install script — no install-logic duplication.worker/addons/dind/entrypoint.d/50-dockerd.sh): startsdockerd --storage-driver=overlay2before tmux takes PID 1. overlay2 (on the ext4-backed anonymous volume, not overlay-on-overlay) is materially faster than the issue's suggested vfs.docker-bake.hcl: curated targets (base, playwright, dind, dind-playwright, webapp) — we build only the tags we offer, not the blind 2^N.--privilegedmode" warning when a dind image is selected.default-CLAUDE.mddocuments the disposable-stack workflow (docker run -p 3001:3001 … ; notify-preview 3001).PR preview images
CI now pushes bounded, per-PR image tags you can pull and spawn:
The tag is overwritten on each push (bounded per PR;
:latestis never moved on branch builds). Apull_request:closedworkflow (.forgejo/workflows/pr-image-cleanup.yml) deletes these on close/merge.⚙️ Operator prerequisites for registry hygiene
PACKAGE_CLEANUP_TOKENsecret — a PAT withwrite:packagescope, so the close-cleanup job can delete tags. Without it the job no-ops (harmless).lz→ Packages → Settings: Remove versions matchingpr-.+, Remove versions older than7days.latestis always kept by the container registry regardless.curl -H "Authorization: token <PAT>" https://x.lck.sh/api/v1/packages/lz?type=containershould list the container packages.Verification
Automated (green):
pnpm lint·pnpm typecheck(0 errors) ·pnpm test(562 pass) ·pnpm build. CIdocker buildx bakebuilds all five targets.⚠️ Runtime NOT yet verified — this was implemented in a non-Docker worker, so the dind runtime path is unverified. Please run the Task 8 checklist against a
pr-<n>-dindimage once CI publishes it:docker versionreports client and server;docker run --rm hello-worldexits clean.docker info --format '{{.Driver}}'→overlay2; buildagent-nexusinside dind — succeeds.docker compose up -d+notify-preview 3001→ operator sees/approves the preview and reaches the inner service.docker versionandplaywright-cli --helpwork (both capabilities applied)./var/lib/dockervolume is reaped (container.remove({ v: true })).HostConfig.Privileged= false, nodockerCLI.Known risks (documented in-code): dind apt install couples to the base's Debian codename (
bookwormtoday); ifdockerdfails to boot on the host kernel, it's most likely cgroup-v2 setup — crib the prep fromdocker:dind'sdockerd-entrypoint.shinto the drop-in.Follow-up (out of scope)
AGENTS.mdfacts #5/#12 still saynode:20-slim, but the base image is alreadynode:22-slim(predates this branch) — worth a doc fix.