Is a Docker Container a VM? It's a Process on Your Kernel

Many developers picture a Docker container as a small virtual machine. It’s actually an ordinary process on your host’s kernel, with limits wrapped around it. That difference decides whether a container is safe enough for code you don’t trust.

In Docker is weird, Nick at Code and Cake writes up what they learned building their own container runtime for fun. Below: the myth, the evidence against it, and what to run instead when isolation matters.

Table of Contents

The myth: a container is a lightweight VM

Most of us met containers as “VMs, but faster.” You get your own filesystem, your own process list and your own network. It looks like a separate machine, so it’s easy to treat it like one.

That mental model works for shipping code. It breaks when you start making security decisions with it.

The evidence: you can find it in /proc

The first finding: “Unlike VMs, containers are just processes with special restrictions on them.” The host kernel is still running that process. If you know where to look, it shows up in the host’s /proc like any other.

The second: “There’s not really a linux feature that’s just ‘containers’.” He calls them “5 different linux kernel features in trenchcoat.”

Images are plain too. Per Nick, an image is a folder Docker stores somewhere. Docker then calls chroot or pivot_root to make that folder the process’s root directory.

What a container really is

Each kernel feature does one job:

  • Namespaces hide what the process can see of the host: other processes, mounts, the network.
  • Cgroups cap how much CPU and memory it can use.
  • A chroot or pivot_root swaps in the image as its filesystem.
  • Network isolation gives it its own interfaces and routes.

None of these adds a second kernel. A VM boots its own kernel on virtual hardware. A container makes system calls straight into yours.

Why the shared kernel matters

The article also notes that the Docker daemon usually runs as root, because many of the kernel APIs a runtime needs used to require it. Rootless runtimes exist now. Their big gap is networking, which they have to reimplement in user space.

Developers in the discussion took this further. One said containers worked out as a developer-experience tool but never became secure enough as infrastructure isolation. Another now unpacks Docker images into Firecracker microVMs, keeping a slim workload while adding a real security boundary. A third pointed at the client and server design itself, which they said makes permission management far harder.

The counterpoint: everything is an abstraction

The best pushback was a joke. One developer looked forward to the follow-up post “where they discover that processes aren’t real either.”

The point stands. Every layer is an abstraction, and calling a container “just a process” can sound like a gotcha. Another developer asked what was weird about any of it, since it all follows from how Linux evolved.

I agree the label matters less than the boundary. The boundary is the reason this myth is worth correcting.

What to do instead

My rule: code I don’t trust runs in a VM, and containers handle the packaging. In practice:

  1. Use containers for what they’re best at: one artifact that runs the same on a laptop and in CI.
  2. For untrusted or multi-tenant code, add a VM boundary. Firecracker microVMs can run from the same images.
  3. Prefer a rootless runtime where you can. Podman starts containers with no root, no daemon and no socket, as one developer pointed out.
  4. To see the pieces yourself, read bocker, Docker in around 100 lines of bash, which a commenter recommended. Its isolation is minimal, so treat it as a lesson only.

Running containers in a cluster? My Kubernetes in production notes cover what changes after hello world.

FAQ

Is a Docker container a virtual machine?

No. A VM runs its own kernel on virtual hardware. A container is a process on the host’s kernel, isolated by namespaces and cgroups.

Do Docker containers share the host kernel?

Yes. Every container on a Linux host makes system calls into the same kernel. A kernel bug can affect all of them at once.

Is Docker secure enough for untrusted code?

It’s a weaker boundary than a VM. For untrusted or multi-tenant workloads, run containers inside a VM, such as a Firecracker microVM.

Why does the Docker daemon run as root?

Many kernel APIs a container runtime uses required root, so the daemon usually runs as root. Rootless runtimes exist, but have to reimplement networking in user space.

What is the difference between Docker and Podman?

Podman can run containers rootless, without a long-running daemon or socket. Docker’s default setup uses a root daemon that clients talk to.

What is a container image?

A folder of files. The runtime makes it the process’s root directory with chroot or pivot_root, then starts your command inside it.

Sources