CLI tool
containerd/nerdctl avatar
containerd/nerdctl

nerdctl: a Docker-compatible CLI for containerd, without the Docker daemon

contaiNERD CTL - Docker-compatible CLI for containerd, with support for Compose, Rootless, eStargz, OCIcrypt, IPFS, ...

10,392 stars831 forksGoApache-2.0

At a glance

What is it?
nerdctl gives you docker-style commands against containerd directly, plus lazy pulling, image encryption and cosign verification that Docker does not ship. It is a non-core containerd sub-project, and it expects you to bring containerd, CNI plugins and optionally BuildKit yourself.
Who is it for?
Adopt nerdctl if you already run containerd, want a docker-shaped command line against it, and need features such as Stargz lazy pulling, ocicrypt image encryption or cosign verification. Do not adopt it as a drop-in replacement if you depend on Docker Desktop, Docker Swarm or Docker's plugin ecosystem, and do not expect it to manage Kubernetes workloads: the README says debugging Kubernetes clusters is not the primary goal, even though --namespace k8s.io works.
Can I use it commercially?
Yes. Apache-2.0 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 10 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 September 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What nerdctl is for, and who actually needs it

containerd is the container runtime that sits underneath a lot of tooling, but it does not ship a user-facing command line of its own beyond ctr, which is a low-level debugging tool rather than something you would hand to a build engineer. nerdctl fills that gap. The README describes it as a Docker-compatible CLI for containerd and lists the goal plainly: to facilitate experimenting with features of containerd that are not present in Docker. Competing with Docker is explicitly not the goal, and the README says those features are expected to eventually appear in Docker as well.

That framing matters when you decide whether to adopt it. The audience is people who already run containerd, or who are willing to, and who want a familiar command surface on top of it. If you are on a Kubernetes node and want to inspect what is actually running there, nerdctl --namespace k8s.io ps -a gives you a container listing that ctr does not format for humans. If you are evaluating lazy image pulling, encrypted images or P2P distribution, nerdctl is the CLI where those snapshotter and imgcrypt integrations are exposed. If none of that describes you, the tool adds a dependency without removing one.

How nerdctl talks to containerd, and where the features live

nerdctl is a Go binary that speaks to containerd over its API rather than through the Docker daemon. The go.mod shows direct dependencies on github.com/containerd/containerd/v2, the containerd API module, go-cni, imgcrypt, the stargz-snapshotter packages, the nydus-snapshotter package and accelerated-container-image. Those imports are the architecture in miniature: the CLI is a client, and the optional capabilities are wired in by talking to the corresponding containerd snapshotters and libraries rather than by reimplementing them.

Namespacing is the clearest example of the model. containerd organises containers into namespaces, and nerdctl exposes that directly with --namespace. The README notes that all Kubernetes containers live in the k8s.io containerd namespace regardless of Kubernetes namespaces, which is why a single flag switches the whole view. Lazy pulling follows the same pattern: nerdctl --snapshotter=stargz|nydus|overlaybd|soci run IMAGE selects a snapshotter for that invocation. Image encryption is a subcommand pair, nerdctl image encrypt and nerdctl image decrypt. Cosign support appears as flags on pull and push, and the README says it also works in Compose. IPFS distribution is opt-in and the README is explicit that your host is not connected to any P2P network unless you install and run an IPFS daemon.

The build path is separate. nerdctl build delegates to BuildKit, so buildkitd has to be running. The README recommends BuildKit v0.11.0 or later and notes that some features, including pruning caches with nerdctl system prune, do not work with older versions. Networking for nerdctl run comes from CNI plugins, with v1.1.0 or later highly recommended.

Installing nerdctl and running a first container

The README points at the GitHub releases page for binaries and distinguishes two archives. nerdctl-full-<VERSION>-<OS>-<ARCH>.tar.gz bundles containerd, CNI plugins, BuildKit, RootlessKit and the rest, while nerdctl-<VERSION>-<OS>-<ARCH>.tar.gz contains only nerdctl. On a machine that already has containerd and CNI plugins, the plain archive is enough. On a fresh host, the full archive saves you from assembling the dependency list by hand.

On Linux, brew is a supported path:

bash
brew install nerdctl

After installing, the first useful check is a container on the default bridge CNI network, which the README gives as 10.4.0.0/24:

bash
nerdctl run -it --rm alpine

If that drops you into a shell, containerd and the CNI plugins are both reachable. To build instead of pull, start buildkitd first, then:

bash
nerdctl build -t foo /some-dockerfile-directory
nerdctl run -it --rm foo

The README also shows sending build output to a local directory rather than an image store, using nerdctl build -o type=local,dest=. /some-dockerfile-directory. Compose files work through a subcommand:

bash
nerdctl compose -f ./examples/compose-wordpress/docker-compose.yaml up

The repository ships examples/compose-wordpress and examples/compose-multi-platform if you want a file that is known to match the current CLI. For rootless use, the README gives containerd-rootless-setuptool.sh install to launch rootless containerd, after which nerdctl run -d -p 8080:80 --name nginx nginx:alpine works as a normal user. RootlessKit needs to be v0.10.0 or later, with v3.0.0 or later recommended.

On macOS there is no native install. The README routes you through Lima:

bash
brew install lima
limactl start
lima nerdctl run -d --name nginx -p 127.0.0.1:8080:80 nginx:alpine

On Windows, Scoop is the documented path with scoop install nerdctl, and the README states that Linux containers are known to work on WSL2 while Windows containers are experimental. FreeBSD is covered by a separate document in docs/.

Where nerdctl is the wrong tool

The most common mistake is treating nerdctl as a drop-in Docker replacement and then discovering the parts that are not there. The README frames the project as a way to experiment with containerd features, not as a Docker substitute, and it says the advanced features are expected to reach Docker eventually. That is a signal about long-term positioning: you are adopting a CLI that follows containerd, not a product with its own roadmap for competing with Docker.

Kubernetes debugging is the second trap. nerdctl --namespace k8s.io ps -a works and the README shows it, but the same README says nerdctl might be useful for debugging Kubernetes clusters while making clear that this is not the primary goal. If your job is inspecting pods, crictl and kubectl are built for that, and the container listing nerdctl produces is a containerd view with a k8s:// name prefix rather than a Kubernetes view. The README marks log reading in that namespace as experimental.

Dependency drift is the third. BuildKit older than v0.11.0 breaks features such as nerdctl system prune, and CNI plugins older than v1.1.0 are only tolerated rather than recommended. Because nerdctl-full bundles pinned versions, mixing a plain nerdctl binary with an older system containerd or an old plugin set is where behaviour stops matching the documentation. The repository's own Dockerfile pins containerd, runc, CNI plugins, BuildKit, stargz-snapshotter, imgcrypt, RootlessKit and bypass4netns to specific versions, which tells you the project treats these as a tested set rather than independent choices.

nerdctl vs docker and nerdctl vs podman: what actually differs

The README's own comparison is with Docker, and it is a feature-list comparison rather than a philosophical one. Docker runs a daemon that nerdctl does not need, because containerd is already the runtime underneath. The features nerdctl lists as absent from Docker are lazy pulling through the Stargz, Nydus, OverlayBD and SOCI snapshotters, ocicrypt image encryption and decryption, IPFS-based P2P distribution, cosign signing and verification on pull and push, and bypass4netns acceleration for rootless containers via nerdctl run --annotation nerdctl/bypass4netns=true. The minor list includes containerd namespacing and exporting Docker or OCI images.

Podman takes a different route to a similar destination. It is daemonless too, but it is not built as a client of containerd in the way nerdctl is: nerdctl's whole command surface is a thin layer over containerd's namespaces, snapshotters and API, which is why a snapshotter flag or a namespace flag changes what the same command does. If your infrastructure already standardises on containerd, that alignment is the argument for nerdctl. If you want a container tool that is independent of the runtime underneath, nerdctl is the wrong shape for that goal, because its feature set is containerd's feature set.

Against ctr, the difference is usability rather than capability. ctr is the low-level containerd client intended for debugging; nerdctl reproduces Docker's UI and UX, adds Compose, and formats output for humans. Against crictl, the difference is scope: crictl speaks the CRI and is aimed at Kubernetes node debugging, while nerdctl speaks containerd directly and covers image building and Compose, which CRI does not.

Licence, releases and what upgrades cost you

nerdctl is Apache-2.0, and the source files carry the standard Apache header, including the Dockerfile and Makefile. The repository also contains a NOTICE file, which is the usual companion to an Apache-2.0 distribution and is worth reading if you redistribute the binary or the bundled nerdctl-full archive, since that archive includes third-party components under their own licences. This is a description of what the repository contains, not legal advice; if you ship the full archive inside a product, check the individual component licences.

Upgrade cost is dominated by the bundled dependency set rather than by nerdctl's own code. The Dockerfile pins containerd, runc, CNI plugins, BuildKit, stargz-snapshotter, imgcrypt, RootlessKit, bypass4netns, fuse-overlayfs, tini, buildg and gomodjail to explicit versions, so a nerdctl release is effectively a tested combination. If you install the plain binary against a containerd you manage yourself, you own that compatibility matrix. The release history shows both stable and beta tags: v2.3.5 and v2.3.4 are stable releases, while v2.4.0-beta.0 is a beta. The go.mod requires Go 1.26.3 and depends on a containerd v2.4.0-beta.0 module, which means building from source pulls you onto pre-release containerd code even when the nerdctl tag itself is stable. The last push to the default branch was on 2026-08-24.

Editorial conclusion

Adopt nerdctl if you already run containerd, want a docker-shaped command line against it, and need features such as Stargz lazy pulling, ocicrypt image encryption or cosign verification. Do not adopt it as a drop-in replacement if you depend on Docker Desktop, Docker Swarm or Docker's plugin ecosystem, and do not expect it to manage Kubernetes workloads: the README says debugging Kubernetes clusters is not the primary goal, even though --namespace k8s.io works. Before committing, verify on your own hosts that CNI plugins v1.1.0 or later are present, that buildkitd is running if you need nerdctl build, and that nerdctl compose accepts your existing docker-compose.yaml. The repository's latest release at the time of writing was v2.4.0-beta.0, so pin a stable tag such as v2.3.5 rather than a beta if you are deploying this in production.

Frequently asked questions

What is nerdctl?

It is a Docker-compatible CLI for containerd, described in the README as a non-core sub-project of containerd. It offers the same UI and UX as docker and adds optional features such as lazy pulling, image encryption, IPFS distribution and cosign verification.

What are the key differences between Docker and nerdctl?

nerdctl talks to containerd directly instead of going through the Docker daemon, and the README lists features it has that Docker does not: lazy pulling with the stargz, nydus, overlaybd or soci snapshotters, ocicrypt image encryption and decryption, IPFS-based distribution, cosign signing and verification, and bypass4netns for rootless containers. The README states that competing with Docker is not the goal and that those features are expected to reach Docker eventually.

How do I install nerdctl on Ubuntu?

The README points to the GitHub releases page for binaries and notes that brew install nerdctl works on Linux systems. The nerdctl-full archive bundles containerd, CNI plugins, BuildKit and RootlessKit, while the plain nerdctl archive does not include those dependencies.

How do I install nerdctl on Windows?

The README gives Scoop as the install path, with scoop install nerdctl. It notes that Linux containers are known to work on WSL2, while Windows containers are experimental.

How do I install nerdctl on macOS?

There is no native macOS install. The README routes macOS users through Lima: brew install lima, then limactl start, after which lima nerdctl run works inside the Linux virtual machine.

Official sources

  1. Official README
  2. Project repository
  3. Release notes
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/containerd-nerdctl.svg)](https://hysenlabs.com/projects/containerd-nerdctl)