docker/docker

The legacy Go client library for the Docker Engine API, used to build and manage containers, images, and daemons programmatically.

SDK
Go
vv28.5.2+incompatible
72,200 stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
97 /100 Excellent
Development Activity 96
Maintenance 96
Community 96
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
77 /100 Good
Architecture 62
Code Quality 88
Innovation 68
Learning Curve 90

github.com/docker/docker is the original Go module path for the Docker Engine, the same codebase that today lives on as the Moby Project. For years it was how Go programs talked to the Docker daemon: importing docker/docker/client and docker/docker/api/types to list containers, build images, and drive the exact operations the docker CLI itself uses.

As of Docker v29 (released November 2025), this import path is deprecated and frozen; new development happens under github.com/moby/moby/client and github.com/moby/moby/api instead. Existing code that already imports docker/docker continues to build against the last tagged release, but new projects should migrate to the split client/api modules to get future updates and security fixes.

What You Get

  • A typed HTTP client (client.Client) covering every Docker Engine API endpoint: containers, images, networks, volumes, exec, swarm, and system info
  • Shared API request/response types under api/types so client calls and daemon responses use the same structs
  • Automatic API version negotiation against the daemon it connects to
  • Environment-based client configuration via client.FromEnv (DOCKER_HOST, DOCKER_API_VERSION, DOCKER_CERT_PATH, DOCKER_TLS_VERIFY)

Common Use Cases

  • Building custom container orchestration or CI tooling that needs to start, stop, and inspect containers programmatically
  • Writing integration tests that spin up throwaway containers as test fixtures
  • Building internal developer platforms that wrap docker build/push behind an API
  • Monitoring a Docker host by polling container and system stats through the API instead of shelling out to the CLI

Under The Hood

Architecture

The docker/docker module root is the full Moby Engine monorepo; the portion actually consumed via this legacy import path is client/ (the HTTP client, with per-resource files like container_list.go and image_build.go) and api/types/ (shared request/response structs generated from an API swagger definition). The client wraps a single http.Client plus a transport abstraction (client_unix.go/client_windows.go) that dials either a TCP+TLS endpoint or a local Unix/Windows socket, giving callers one uniform client.Client interface regardless of transport. Version negotiation happens once per client instance against the daemon’s version endpoint, then every subsequent call embeds the negotiated version in its request path. Because the module also contains the daemon, builder, and swarm orchestration code, importing anything outside client/ and api/ pulls in the full engine dependency graph, which is exactly why the project split the client and API packages into their own go.mod files under the newer moby/moby/v2 layout, and why this combined legacy path is now frozen.

Tech Stack

The client itself has a modest dependency footprint compared to the engine: go-winio for Windows named pipes, docker/go-connections and docker/go-units for connection dialing and byte-size formatting, opencontainers/image-spec and go-digest for OCI-compatible image references, and OpenTelemetry’s otelhttp for optional request tracing. The split client and api modules require Go 1.24+, while the engine root now requires a newer Go toolchain. Requests are plain net/http calls against the Engine API’s versioned REST+JSON surface, with no client-side code generation; request and response shapes are hand-maintained Go structs.

Code Quality

client/ carries over a hundred *_test.go files alongside their implementation files, one test file per endpoint, using the standard testing package plus gotest.tools for assertions and an in-process fake transport rather than a real daemon. Errors are wrapped through containerd’s errdefs packages to preserve not-found/conflict/unauthorized semantics across the wire instead of returning opaque strings. The wider engine repository runs an extensive CI matrix across Linux and Windows, static analysis, and supply-chain scanning, among the more thorough setups of any Go project in this catalog.

API Design The client’s functional-options pattern for construction keeps setup terse while remaining extensible without breaking signatures, and its environment-driven configuration mirrors the exact variables the docker CLI itself honors, so code written against this client behaves identically to the CLI in the same environment. The tradeoff is that this legacy import path bundles the client inside the full engine module, so consumers pull in package layout meant for the daemon, not just the SDK, exactly the friction the project’s split into separate client and api modules was designed to fix. Method naming maps directly to REST resources and verbs, which is predictable but produces a very large single client interface rather than resource-scoped sub-clients.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers