For years “Docker” was synonymous with “containers”. But the actual architecture underneath has changed: containerd is today the standard container runtime in Kubernetes and many other platforms, and Docker (the daemon) is just one of the layers wrapping it. nerdctl offers an alternative: the familiar Docker CLI but talking directly to containerd.
How We Got Here
Until 2020, Kubernetes ran containers through Docker Engine. In 2020 they announced dockershim deprecation (the shim translating K8s requests to Docker), and in 2022 they removed it. Since then, the standard K8s runtime is containerd directly, no Docker Engine in between.
containerd has existed since 2014 as a Docker subproject, then donated to the CNCF. It’s smaller and more specialised: only manages container and image lifecycle. No build, UI, Swarm networking, or the other layers Docker Engine added.
The problem: if the container engine = containerd, what do you use on the command line? crictl is too low-level (designed for Kubernetes, not humans). That’s where nerdctl comes in.
What nerdctl Is
nerdctl is a Docker-compatible CLI (yes, many commands are identical: nerdctl run, nerdctl ps, nerdctl build) that talks to containerd directly. Developed by the containerd team itself and distributed officially.
Features it includes that Docker Engine doesn’t natively:
- Rootless support by default. Runs containerd and its containers as unprivileged user with no extra setup.
- Encrypted and signed images. Integration with ocicrypt and cosign for secure supply chain.
- Lazy-pulling. With stargz-snapshotter, starts containers before downloading the whole image — useful for large images.
- Native CNI support. Networks configure with standard CNI plugins, the same Kubernetes uses. Reuses your knowledge.
When Switching Makes Sense
Three scenarios where nerdctl beats Docker Engine:
- Development on machines already running containerd. If your local environment has k3s or Docker Desktop using containerd internally, nerdctl removes the Docker Engine layer. Less memory, fewer processes.
- Consistency with K8s production. If your production cluster uses containerd, developing with the same runtime avoids subtle surprises (storage-driver differences, network handling, cgroups).
- Restricted environments. Rootless containerd + nerdctl works where Docker Engine doesn’t: hosts where you can’t grant root privileges.
Cases Where Docker Engine Still Wins
On the other hand, areas where Docker still leads:
- Tool ecosystem. IDEs, plugins, Docker Desktop extensions — all assume Docker Engine. nerdctl covers almost every command but not every integration.
- Docker Compose. nerdctl has
nerdctl composebut trails compose v3.8+ compatibility and advanced features (profiles, extensions). - Docker Swarm. If you use Swarm as orchestrator, there’s no alternative — nerdctl doesn’t implement Swarm mode.
- Team learning curve. If the whole team knows Docker, switching just for “better technology” rarely pays the transition cost.
Installation and First Steps
On a Linux with containerd already installed (via apt/yum or as part of K8s node):
# Download binary (latest release)
wget https://github.com/containerd/nerdctl/releases/latest/download/nerdctl-full-linux-amd64.tar.gz
tar -xzf nerdctl-full-linux-amd64.tar.gz -C /usr/local/
# First container
nerdctl run --rm hello-world
# List images
nerdctl images
# Run detached
nerdctl run -d -p 8080:80 nginx
The syntax is familiar for anyone coming from Docker. For rootless use:
containerd-rootless-setuptool.sh install
systemctl --user start containerd
nerdctl run --rm hello-world # now runs as your user, no sudo
nerdctl vs podman
podman is another Docker CLI alternative, particularly popular in Red Hat environments. Key differences with nerdctl:
- Runtime: podman uses crun/runc directly, no containerd. nerdctl uses containerd.
- Daemon: podman is daemonless (each command spawns containers with no persistent process). nerdctl requires containerd running.
- Kubernetes: podman can generate K8s manifests (
podman generate kube). nerdctl doesn’t.
For teams living in K8s, nerdctl usually fits better because it reuses the already-installed runtime. For RHEL teams with more independent flows, podman is the natural choice.
Related, see how we’ve covered Docker on Ubuntu 22.04 — the principles translate, only the CLI/engine layer changes.
Conclusion
nerdctl represents the maturation of the container stack: clean separation between runtime (containerd), CLI (nerdctl), orchestrator (K8s). For development environments wanting to align with K8s production, or where rootless is a requirement, the transition pays. For workflows where Docker Engine works well, there’s no urgency — but knowing the alternative is worthwhile.
Follow us on jacar.es for more on containers, Kubernetes, and platform tools.