Pin or override the toolbox image
The kvm, proxmox, and ec2 backends provision through the toolbox
container — Terraform, Task, the libvirt client, and the pinned Go toolchain all
live there so your host needs only Docker. (The vz backend runs limactl on the
host and uses no toolbox at all, so none of this applies to it.)
Which image that container runs is decided by the ztd binary, not by you editing
a compose file.
The rule: released binaries pull, source builds build locally
Your ztd | Image | What Docker does |
|---|---|---|
a release, e.g. 0.4.0 | registry.gitlab.com/frob/ztd/ztd-toolbox:0.4.0 | pulls it once, then reuses it |
a source/dev build (dev, …-snapshot) | ztd-toolbox:local | builds it from docker/Dockerfile when absent |
The pull policy is missing in both cases. That single policy covers both because
Compose resolves “not in the local cache” per image: a registry-qualified tag is
pulled, while ztd-toolbox:local exists in no registry and so falls through to the
build: stanza.
The published tag is the binary’s own version, so an installed ztd and its
toolbox can never drift apart: upgrading ztd moves it to a matching image, and
an old binary keeps pointing at the image it was released with. CI publishes the
image from the same git tag that stamps the binary.
missing (not always) is the pull policy for a release, so once the image has
been fetched a released ztd keeps working offline.
Check what your binary resolved:
ztd config...
toolbox_image = registry.gitlab.com/frob/ztd/ztd-toolbox:0.4.0
toolbox_pull_policy = missingOverride it
Two environment variables, both honored on any build:
# Run a mirror, an air-gapped copy, or your own rebuild.
export ZTD_TOOLBOX_IMAGE=registry.internal.example/ztd-toolbox:0.4.0
# Force a local build of docker/Dockerfile, even on a released binary
# (no registry access, or you're testing a toolbox change).
export ZTD_TOOLBOX_PULL_POLICY=buildSetting ZTD_TOOLBOX_IMAGE alone also switches the policy to missing — a local
build would otherwise overwrite the tag you just asked for. Set
ZTD_TOOLBOX_PULL_POLICY explicitly when you want the other behavior; it always
wins.
Both show up in ztd config, so an override is never invisible.
Private registries
ztd does not handle registry credentials — it only names the image. Log in with
Docker first and the pull works as usual:
docker login registry.internal.exampleBuilding the toolbox yourself
Contributors need nothing special: a source build is a dev build, so
docker/Dockerfile is rebuilt on every run and your edits take effect
immediately. To force a rebuild after changing the Dockerfile on a released
binary, use ZTD_TOOLBOX_PULL_POLICY=build, or build and tag it by hand:
docker build -t "$(ztd config | awk -F' = ' '/^toolbox_image/{print $2}')" ./docker
docker compose runreuses a cached image and will not rebuild on its own when only the Dockerfile changed under a non-buildpolicy — that’s exactly what the policy controls.