feat(docker): give the image the tools template hooks actually call - #148
Merged
Merged
Conversation
The runtime stage shipped bash and nothing else, so a hook got exactly as far as `command not found` — with the tree already written. Running specsnl/specs-laravel-project through the image failed on its first hook (`task: command not found`) and left a scaffold with no .env and no git repo, while `specs use` exited non-zero. Adds git, task, and the docker CLI with the compose plugin, pinned to the same versions the vhs and bats stages already use. git also gets init.defaultBranch=main so a `git init` hook does not hand back `master` where a host would produce `main`. With these, that template now completes all four of its post-use hooks in the container, and the result is identical to the host scaffold apart from one APP_URL line the template's own hook rewrites only on darwin. Documents the sibling-container contract this exposes: a hook running docker needs the socket (--group-add 0 past its root:root 0660) and the work directory mounted at its own path, because the daemon resolves a sibling's bind mounts against the host — at /work the hook asks for a path the host does not have.
The install list and the bats case name already say which tools the image carries and why a hook needs them.
TASK_VERSION, DOCKER_VERSION and COMPOSE_VERSION were repeated across the vhs, bats and debian stages, so a bump meant editing the same number in up to three places. They move to a global ARG block above the first FROM; the stages re-declare the bare names to pull them into scope. The downloads are all `curl | tar`, where the default /bin/sh reports only tar's exit status — a failed download only surfaces because tar happens to choke on the truncated stream. SHELL with -o pipefail puts that back on the shell: bash for the Debian-based stages, busybox ash for the Alpine one. The base stage also drops the apt lists like the other stages already did.
`task lint:docker` runs hadolint through a compose service under the lint profile, the same shape as golangci-lint. CI runs the task itself rather than hadolint/hadolint-action, which ships its own hadolint build and would put the version in a second place to keep in sync. Version pinning is off in .hadolint.yml: pinning every apt/apk package on top of an already pinned base image trades a reproducible build for one that breaks the moment the distro moves a package version.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
git,task, and thedockerCLI + compose plugin to thedebianruntime stage, pinned to the versions thevhsandbatsstages already use.init.defaultBranch mainso agit inithook does not hand backmasterwhere a host producesmain.--group-add 0, and the work directory must be mounted at its own path rather than/work.test/image.batscovering the toolchain, the compose plugin, andgitunder a foreign uid.Why
The runtime stage shipped
bashand nothing else, so a hook got as far ascommand not foundwith the tree already written. Runningspecsnl/specs-laravel-projectthrough the image failed on its first hook (task: command not found), leaving a scaffold with no.envand no git repo whilespecs useexited non-zero.With this, that template completes all four of its
post-usehooks in the container, and the result matches the host scaffold apart from oneAPP_URLline the template's own hook rewrites only on darwin.Mounting at
/workis not enough for hooks that start containers: the daemon resolves a sibling's bind mounts against the host, so the hook asks for a path the host does not have and fails against a tree that looks fine from inside.