THE MISSING LINK: TRANSITIONING FROM DOCKER TO NERDCTL
You’ve felt it. That subtle, creeping weight of Docker Desktop as it slowly consumes your system resources, occasionally popping up a licensing notification that makes you question your life choices. You want the speed of containerd, the familiarity of the Docker CLI, and the ability to actually see into your Kubernetes namespaces without feeling like you’re hacking the Matrix. Welcome to the world of the Docker Refugee.
Who Is This Guide For?
This is for you if you’re a developer wanting to escape Docker Desktop bloat, an engineer wanting containerd power with Docker CLI familiarity, a DevOps professional evaluating container tools, or anyone wanting better Kubernetes integration than Docker provides. Sound like you? Let’s dive in.
By the end of this, you’ll know why nerdctl is the bridge between Docker and containerd, how lazy pulling dramatically speeds up container startup, the command-for-command migration from Docker to nerdctl, and whether to use Lima or direct installation.
Who Is This Guide For?
This is for you if you’re a developer wanting to escape Docker Desktop bloat, an engineer wanting containerd power with Docker CLI familiarity, a DevOps professional evaluating container tools, or anyone wanting better Kubernetes integration than Docker provides. Sound like you? Let’s dive in.
By the end of this, you’ll know why nerdctl is the bridge between Docker and containerd, how lazy pulling dramatically speeds up container startup, the command-for-command migration from Docker to nerdctl, and whether to use Lima or direct installation.
For a long time, the advice for escaping Docker was “just use Podman.” And while Podman is fantastic, it often feels like a parallel universe—close enough to be familiar, but distinct enough to cause friction in complex CI/CD pipelines. As I noted in my container runtime showdown /, the choice often comes down to the tooling rather than the engine itself.
Enter nerdctl. It isn’t just a replacement; it’s the missing link that bridges the gap between the high-level Docker DX and the low-level power of containerd. It’s particularly useful if you’re already running an ultimate local Kubernetes showdown
/ environment and want deeper visibility into your workloads.
The Power of Lazy Pulling
One of the most immediate wins with nerdctl is its native support for “lazy pulling” via eStargz or SOCI snapshotters. In the standard Docker world, you wait for the entire image to download and unpack before the first bit of code executes. With nerdctl, your container can start while the rest of the image is still being streamed in the background. For large machine learning images or heavy Java stacks, this can take your startup time from minutes to single-digit seconds. It’s the kind of performance optimization that makes you realize how much time we’ve been wasting waiting for tarballs to decompress.
The Migration: Command-for-Command
Transitioning to nerdctl doesn’t require a cognitive reset. If you’re on macOS, the easiest path is via Lima
, which does the heavy lifting of setting up the VM and mounting your home directory.
# Install Lima and start the default VM (which uses containerd + nerdctl)
brew install lima
limactl start
# Access nerdctl via the Lima shell
lima nerdctl run -d --name nginx -p 8080:80 nginx:alpine
For the true “Docker Refugee” experience, you can alias the command. Because nerdctl was designed to be a drop-in replacement, most of your muscle memory just works:
alias docker="lima nerdctl"
docker ps
docker images
docker build -t my-app .
Deep Dive: Enabling Lazy Pulling
To actually see the benefits of lazy pulling, you need to use a compatible snapshotter. Here’s how you’d run a container using the stargz snapshotter for instant startup. Note that the example uses a pre-converted image from the stargz-containers repository:
# Run a stargz-optimized image with the stargz snapshotter
# Note: If alpine:3.13-esgz is missing, try a verified tag like 3.10.2-org
nerdctl run --snapshotter=stargz --rm ghcr.io/stargz-containers/alpine:3.10.2-org ls -l
[!TIP] If you’re on macOS using Lima, ensure you have the
stargzsnapshotter enabled in yourlima.yamlor VM configuration. You can also try other pre-converted images likeghcr.io/stargz-containers/node:17.8.0-esgzfor testing.
From Zero to K8s in One Command
Setting up a local Kubernetes cluster usually involves a thick layer of abstractions (like Minikube or Docker Desktop’s built-in cluster). But as a Docker refugee, you probably want something more transparent. Using lima and k3s, you can spin up a production-grade (albeit single-node) cluster that uses containerd as its native runtime in seconds.
# Start a new Lima VM with the k3s template
limactl start --name=k8s template://k3s
# Export the kubeconfig to point to your new cluster
export KUBECONFIG=$(lima --name=k8s sudo cat /etc/rancher/k3s/k3s.yaml)
# Verify your node is ready
kubectl get nodes
The beauty of this setup is that nerdctl is already there, pre-installed and configured to talk to the same containerd instance that K3s is using. This is the ultimate “peek behind the curtain” setup for local development.
Seeing Through the K8s Lens
If you’ve ever run a local Kubernetes cluster (like k3s or kind), you know the frustration: docker ps is completely blind to the containers running inside your cluster because they live in a different containerd namespace. nerdctl solves this by being namespace-aware.
# List containers in the Kubernetes namespace
nerdctl --namespace k8s.io ps
# Inspect a specific K8s pod container
nerdctl --namespace k8s.io inspect <container-id>
Security Without the Setup
Security shouldn’t be a secondary consideration, yet setting up rootless Docker often feels like a rite of passage. nerdctl was built with a rootless-first mindset. It integrates seamlessly with Lima on macOS and Linux, giving you a secure, isolated environment without the administrative overhead.
Unlike Docker, where rootless mode often requires specialized flags or separate binaries, nerdctl rootless is determined by the containerd instance it connects to. If you’ve run the containerd-rootless-setuptool.sh install script, your default nerdctl commands will already be running in a fully isolated, unprivileged namespace.
# Run a container rootless (automatic if your daemon is rootless)
nerdctl run -it --rm alpine
Replacing Docker doesn’t have to mean relearning everything. By focusing on the runtime that’s already powering your production workloads, you get a tool that’s faster, leaner, and more capable of handling the realities of 2026 container orchestration.