Migrate Docker SDK to moby/moby v29 to fix docker/* CVEs
Why this is necessary
github.com/docker/docker and github.com/docker/cli carry several
HIGH/MEDIUM CVEs (see the issue). Their fixes only exist in v29, and
github.com/docker/docker has no v29 release — at v29 the Docker Engine
SDK was split out of that module into two dedicated ones:
github.com/moby/moby/api— the API typesgithub.com/moby/moby/client— the client plus its option/result types
So the fix is not a version bump; it requires migrating off
github.com/docker/docker onto github.com/moby/moby/{api,client} and bumping
github.com/docker/cli to v29. A plain "bump cli to v29" was attempted in
!6463 (closed) and could not
compile, because cli v29 already returns moby types.
What this does
- go.mod: drop
docker/docker, addmoby/moby/api+moby/moby/client, bumpdocker/clito v29.6.1. Adds anexcludefor themoby/mobyv28 monolith so module resolution doesn't pull it back in beside the splitapimodule. - Rewrites the
helpers/docker.Clientadapter for the v29 SDK (option-struct params, result-struct returns) while keeping the interface callers use unchanged. - Handles genuine v29 data-model changes in the docker executor:
HostConfig.DNS([]netip.Addr), MAC addresses (network.HardwareAddr), per-network container IPs, exposed-port handling, and disconnect-via-inspect. - Updates tests and regenerates mocks.
Approaches considered
- Bump the dependency versions only — not possible:
docker/dockerhas no v29, and cli v29 forces moby types. This is the wall the earlier renovate MR hit. - Migrate the interface to mirror the v29 SDK (option-in/result-out everywhere) — most faithful to upstream, but pushes the new call shapes onto every executor call site: a much larger, riskier diff.
- Keep the runner's
docker.Clientinterface stable and translate to v29 inside the adapter (chosen) — the runner already wraps the SDK behind its own interface for insulation and mockability, so this leans on that. The v29 churn is confined to one adapter file plus the executor's real data-model changes; callers and tests barely move. Smallest, most reviewable diff for a security fix.
Reviewing
Most of the diff is mechanical: regenerated mocks (~380 lines) and
import/type renames in tests. The substantive logic is commit 2
(docker.go) plus the adapter (official_docker_client.go /
options.go).
The change is compile-atomic (the CVE-bearing module can't be dropped without moving every import at once), so it is one MR structured as ordered commits for reading, not for bisection — intermediate commits don't individually compile; only the final state builds:
- Migrate Docker SDK ... moby/moby v29 — go.mod + adapter/interface + mechanical renames
- Adapt Docker executor to moby v29 data-model changes —
docker.go, the real logic (worth the closest read) - Update Docker executor tests for moby v29 SDK
- Regenerate Docker client mocks for moby v29
Verification
go build ./...; docker unit and integration test packages compile; docker
unit tests pass; golangci-lint (v2.12.1) reports no issues on the changed
packages.
Closes https://gitlab.com/gitlab-org/gitlab-runner/-/issues/39536