Self-hosted service
fsouza/go-dockerclient avatar
fsouza/go-dockerclient

go-dockerclient: the pre-official Docker client that refuses to disappear

Go client for the Docker Engine API.

2,249 stars555 forksGoBSD-2-Clause

At a glance

What is it?
fsouza's Go client for the Docker Engine API predates Docker's own SDK, is now built on the Moby client packages, and is maintained strictly on demand rather than tracking every new API feature.
Who is it for?
The honest reason to reach for go-dockerclient is that an existing codebase already depends on it. It covers the Engine API, Swarm extensions and the network API, it is on Go modules, it is built on the Moby client packages rather than on hand-rolled HTTP, and the last push is dated 2026-09-28, so it is not abandoned.
Can I use it commercially?
Yes. BSD-2-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 7, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A client that existed before Docker had a Go SDK

The framing sentence in the README is chronological, and it is the whole story of this repository. go-dockerclient was created before Docker had an official Go SDK, and it is still maintained and active because it is still used in the wild. That combination, an incumbent library with real dependents and no first-party mandate behind it, explains both its strengths and its limitations.

The limitation is stated as plainly as the strength. New features in the Docker API do not get implemented automatically here. The development model is on demand: someone files an issue or a pull request, and the feature may then be implemented and merged. The README then says outright that for new projects the official SDK is probably more appropriate, because go-dockerclient lags behind it.

The scale suggests a substantial installed base. There are 2,248 stars and 555 forks, a fork count high enough to indicate copies in production systems rather than casual interest, against 17 open issues. The licence is BSD-2-Clause, the language is Go, the repository is not archived, and the last push is dated 2026-09-28. The project homepage points at the Go package documentation rather than a separate site.

The scope is the Docker remote API plus two extensions: the Swarm API, and Docker's network API, which the README describes as a simple passthrough to the libnetwork remote API. The authoritative reference for anything not covered here is Docker's own remote API documentation.

The first example is a list of images

The README's opening example is deliberately minimal. It constructs a client from the environment, lists images, and prints a few fields from each one. Trimming the print loop, the shape is:

go
package main

import (
	"fmt"

	docker "github.com/fsouza/go-dockerclient"
)

func main() {
	client, err := docker.NewClientFromEnv()
	if err != nil {
		panic(err)
	}

Two details carry over into everything else. The import is aliased to `docker`, which is the convention almost every example in the ecosystem uses. And `NewClientFromEnv` reads the standard environment variables rather than taking an endpoint string, which means the same code works against a local socket, a remote TCP endpoint, or a Docker Machine without modification.

Those variables are named in the README: `DOCKER_HOST`, `DOCKER_TLS_VERIFY`, `DOCKER_CERT_PATH` and `DOCKER_API_VERSION`. That last one matters more than it looks, because it is the mechanism by which you pin a client to a daemon whose API version differs from the client's default. The example then calls `client.ListImages` with a `ListImagesOptions` struct whose `All` field decides whether intermediate images come back too, and the response type carries `ID`, `RepoTags`, `Created`, `Size`, `VirtualSize` and `ParentID` fields.

Connecting to a TLS-enabled daemon

For a daemon with TLS enabled, the README directs you to `NewTLSClient`, passing the endpoint plus paths to the certificate, key and certificate authority. The example reads the certificate directory from the same `DOCKER_CERT_PATH` environment variable and derives the three filenames from it:

go
	const endpoint = "tcp://[ip]:[port]"
	path := os.Getenv("DOCKER_CERT_PATH")
	ca := fmt.Sprintf("%s/ca.pem", path)
	cert := fmt.Sprintf("%s/cert.pem", path)
	key := fmt.Sprintf("%s/key.pem", path)
	client, _ := docker.NewTLSClient(endpoint, cert, key, ca)

This is the standard mutual TLS arrangement for remote Docker access: the client presents a client certificate, the daemon presents a CA-signed certificate, and both verify each other. The three filenames, `ca.pem`, `cert.pem` and `key.pem`, are the ones Docker's own tooling writes.

Two observations. First, the example ignores the returned error with a blank identifier, which is fine for a snippet and a bad habit to copy, since a TLS client that fails to build is the kind of thing you want to fail loudly on rather than discover at the first request. Second, the example's import block lists only `fmt` while the body calls `os.Getenv`, so the snippet as printed would not compile on its own. That is a documentation slip rather than a design problem, but it is the sort of detail worth noticing when you are reading a README written years before Go made blank imports and errors a routine concern.

The README also notes that `NewClientFromEnv` works for docker-machine and other tools that export the same variable set, which is the fallback when you do not want to construct the TLS client by hand.

Now built on Moby's own client packages

The dependency list is the most reassuring thing in the repository, and it is not visible from the README at all. `go.mod` declares the module as `github.com/fsouza/go-dockerclient` on Go 1.26, and it depends on `github.com/moby/moby/client` at v0.6.0 and `github.com/moby/moby/api` at v1.56.0.

That changes the competitive picture described in the README's comparison section. A library that says it lags behind the official SDK sounds worrying until you learn that the transport, types and protocol handling now come from Moby's own extracted packages. The gap between the two is mostly in surface area, not in how requests are actually made.

The remaining dependencies are sensible for the job: `moby/go-archive` for the container archive endpoints, `moby/patternmatcher` for filter patterns, `docker/go-units` for parsing and formatting size and duration values, `Microsoft/go-winio` for Windows named pipe support, `gorilla/mux` for routing, and `google/go-cmp` for test comparison. The transitive list pulls in containerd's log package, klauspost's compress library, Moby's user and userns helpers, and OpenContainers digest and image-spec packages.

There is also a `DOCKER-LICENSE` file in the tree alongside the project `LICENSE`. That is a deliberate piece of housekeeping: the package depends on Docker and Moby code, so the upstream licensing travels with the source rather than being left for a reader to work out.

A file per endpoint, and the tests prove the layout

The repository tree is organised in a way that makes the API surface easy to browse. Rather than one large file, there is a `container_` file per operation: `container_create.go`, `container_start.go`, `container_stop.go`, `container_restart.go`, `container_kill.go`, `container_pause.go`, `container_rename.go`, `container_resize.go`, `container_logs.go`, `container_stats.go`, `container_changes.go`, `container_commit.go`, `container_copy.go`, `container_export.go`, `container_archive.go`, `container_attach.go`, `container_list.go`, `container_inspect.go`, `container_remove.go` and `container_prune.go`.

The naming convention is the documentation. If you want to know whether a Docker operation is supported, you look for the file. Most have a matching `_test.go` alongside, which tells you the operation is covered.

Platform-specific code is separated too, with `client_unix.go` and `client_windows.go` plus their tests, since connecting to a local daemon means different things on Unix sockets and Windows named pipes. Beyond containers the tree continues into other areas, with `client.go` and `auth.go` as the core, and `change.go` for filesystem change inspection.

The test setup is visible in the Makefile. It enables the race detector on amd64 only, runs `go test` with the race flag and `-vet all`, and gates everything on lint: golangci-lint and staticcheck are installed and run as prerequisites of the test target. There is a separate `integration` target that runs tests behind the `docker_integration` build tag, so the suite that talks to a real daemon is explicitly separated from the unit tests. There is also `client_stress_test.go` in the tree, which suggests the client has been exercised under load rather than only against a single container.

Editorial conclusion

The honest reason to reach for go-dockerclient is that an existing codebase already depends on it. It covers the Engine API, Swarm extensions and the network API, it is on Go modules, it is built on the Moby client packages rather than on hand-rolled HTTP, and the last push is dated 2026-09-28, so it is not abandoned. The counterweight is equally plain from the README: new Docker API features are implemented on request rather than automatically, and the author states that for new projects the official SDK is probably the better choice. If you are starting fresh, read that section and take the recommendation. If you are maintaining something that already imports it, the file-per-endpoint layout and the `NewClientFromEnv` entry point make the surface easy to navigate.

Frequently asked questions

What is go-dockerclient and what does it cover?

It is a Go client for the Docker remote API, plus support for the Swarm API extensions and Docker's network API, which the README describes as a passthrough to the libnetwork remote API. It predates Docker's official Go SDK and is now built on Moby's own client and API packages as declared in go.mod.

Should I use go-dockerclient or the official Docker SDK for Go?

The README answers this directly: for new projects the official SDK is probably more appropriate, because go-dockerclient lags behind it and does not automatically pick up new Docker API features. Implementation there is on demand, through an issue or pull request. The library is still maintained, so it remains reasonable for codebases that already depend on it.

How do I create a go-dockerclient client for a TLS daemon?

Use `NewTLSClient`, passing the endpoint along with the paths to the certificate, the key and the certificate authority. In the README's example the three paths are derived from the `DOCKER_CERT_PATH` environment variable as `ca.pem`, `cert.pem` and `key.pem`, which are the filenames Docker's own tooling writes.

How do I know whether a Docker API call is supported?

The repository is organised as one file per container operation, so `container_create.go`, `container_logs.go`, `container_prune.go` and the rest are effectively an index of the supported surface, and most have a matching test file. Since new API features are added on request rather than automatically, an absent file is a reliable signal that the call is not implemented.

Official sources

  1. fsouza/go-dockerclient on GitHub
  2. License: BSD-2-Clause
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/fsouza-go-dockerclient.svg)](https://hysenlabs.com/projects/fsouza-go-dockerclient)