nerdctl lets you use docker commands with containerd as the underlying runtime.
Imagine you’ve got containerd chugging away, managing your containers, but you’re used to the familiar docker CLI. nerdctl is the bridge. It’s a command-line interface that speaks the docker language but translates those commands into actions for containerd. This means you get the ease of docker commands without needing the full docker daemon running, relying instead on the more lightweight containerd.
Let’s see it in action. First, ensure containerd is running. You can check its status with sudo systemctl status containerd. If it’s not active, start it with sudo systemctl start containerd.
Now, install nerdctl. The easiest way is often via your distribution’s package manager, or by downloading a pre-built binary. For example, on Ubuntu, you might do:
wget https://github.com/containerd/nerdctl/releases/download/v1.7.5/nerdctl-1.7.5-linux-amd64.tar.gz
sudo tar xzf nerdctl-1.7.5-linux-amd64.tar.gz -C /usr/local/bin
After installation, you can start using docker commands. Let’s pull an image:
nerdctl pull alpine:latest
This command tells nerdctl to fetch the alpine image. nerdctl then communicates with the local containerd instance, which handles the actual download from the registry.
Now, let’s run a container from that image:
nerdctl run -d --name my-alpine alpine:latest sleep infinity
Here, nerdctl run initiates a new container. The -d flag detaches it from the terminal, --name my-alpine assigns a name, and alpine:latest specifies the image. sleep infinity is just a command to keep the container running indefinitely. containerd is responsible for creating and managing the lifecycle of this container, including setting up its filesystem, network, and process.
You can list running containers:
nerdctl ps
And see the output:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a1b2c3d4e5f6 alpine:latest sleep infinity 2 seconds ago Up 2 seconds my-alpine
To stop and remove the container:
nerdctl stop my-alpine
nerdctl rm my-alpine
nerdctl stop sends a signal to containerd to terminate the container gracefully, and nerdctl rm instructs containerd to clean up its resources.
The mental model behind nerdctl is straightforward: it’s a user-facing CLI that abstracts containerd’s lower-level APIs. containerd itself is a daemon that manages the container lifecycle – pulling images, creating containers, starting, stopping, and removing them, and managing their storage and networking. nerdctl essentially acts as a client to the containerd API, typically via its gRPC interface. This means you can use familiar commands like pull, run, ps, images, build, and push without the overhead of the Docker daemon. The configuration for nerdctl often involves pointing it to the correct containerd socket, usually located at /run/containerd/containerd.sock.
One crucial aspect that often trips people up is how nerdctl handles image and container storage. Unlike the traditional Docker daemon which has its own dedicated storage driver (like overlay2), containerd leverages stargz and nydus for efficient image distribution and runtime, and it manages its own root filesystem directories, typically under /var/lib/containerd/. nerdctl interacts with these underlying mechanisms, so when you’re inspecting storage or cleaning up, you’re indirectly interacting with containerd’s storage management, not Docker’s. This can lead to confusion if you’re expecting Docker’s specific directory structures or commands to work.
The next step is often exploring how nerdctl integrates with Kubernetes, particularly through the nerdctl shim.