Skip to main content

Docker Daemon

The background service (dockerd) that manages Docker objects — images, containers, networks, and volumes. The Docker CLI communicates with the daemon via a REST API over a Unix socket at /var/run/docker.sock.

What the Docker daemon does

The Docker daemon (dockerd) does the actual work behind every Docker command. When you run docker run nginx, the CLI sends a request to the daemon. The daemon pulls the image if needed, sets up networking and volumes, and asks lower-level components to start the container. The CLI is only a client.

%%{init: {'themeVariables': {'fontSize': '18px'}, 'flowchart': {'nodeSpacing': 40, 'rankSpacing': 45, 'padding': 14}}}%% flowchart TD CLI["docker CLI
sends the request"] --> D["dockerd
images, networks, volumes"] D --> C["containerd
container lifecycle"] C --> R["runc
namespaces and cgroups"] R --> P["Container process"] class CLI,C,R,P base class D key classDef base fill:#f8fafc,stroke:#94a3b8,stroke-width:1.5px,color:#0f172a classDef key fill:#dbeafe,stroke:#2563eb,stroke-width:2px,color:#0f172a

Kubernetes talks to containerd directly through the CRI, bypassing dockerd. This is why Kubernetes could drop Docker as a runtime and still run Docker-built images.

The Docker socket

The CLI reaches the daemon through the Unix socket /var/run/docker.sock. You can call the same REST API yourself:

Bash
ls -la /var/run/docker.sock
# srw-rw---- 1 root docker ... /var/run/docker.sock
curl --unix-socket /var/run/docker.sock http://localhost/containers/json
# Same data as: docker ps

Only root and members of the docker group can use the socket.

Configuration

The daemon reads /etc/docker/daemon.json. A typical production file:

JSON
{
"log-driver": "json-file",
"log-opts": { "max-size": "100m", "max-file": "5" },
"storage-driver": "overlay2",
"live-restore": true
}
  • log-driver and log-opts set the default logging driver and rotate logs at 100MB, keeping 5 files.
  • storage-driver selects overlay2, the recommended driver on modern Linux.
  • live-restore keeps containers running while the daemon restarts.
Bash
sudo systemctl status docker # Check the daemon
sudo systemctl restart docker # Restart (stops containers unless live-restore is on)
sudo journalctl -u docker.service -f # Follow daemon logs
docker info # Runtime, storage driver, containers, resources

Troubleshooting

Problem Symptom Fix
Daemon not running Cannot connect to the Docker daemon sudo systemctl start docker
Permission denied permission denied while trying to connect Add the user to the docker group, then log out and back in
Daemon fails after editing config Start-up error Check daemon.json for JSON syntax errors
Containers stop on daemon restart live-restore not enabled Add "live-restore": true to daemon.json
Disk full No space left on device docker system prune to remove unused objects
Tip

Enable live-restore before running production workloads. Without it, every daemon restart or upgrade stops all running containers.

Security

Access to the Docker socket is effectively root access on the host. Never mount it into containers you do not fully trust, never expose it over TCP without mutual TLS, and audit who belongs to the docker group.

Frequently Asked Questions

What exactly happens when you run a docker command — where does the CLI end and the daemon begin?

The `docker` command you type is just a thin client; it serializes your request and sends it as a REST API call to `dockerd`, typically over the Unix socket at `/var/run/docker.sock` on Linux (or a named pipe on Windows). The daemon is the process that does the work: pulling image layers, creating namespaces and cgroups through containerd and runc, and managing the container lifecycle. That is why the CLI can be swapped out (Docker Desktop, remote Docker contexts) without touching daemon internals.

Why is exposing the Docker socket to a container considered a serious security risk?

Mounting `/var/run/docker.sock` into a container (a common pattern for CI runners or monitoring tools) effectively gives that container root access to the host, because the daemon runs as root and anyone who can talk to it can start a new privileged container with the host filesystem mounted in. If a container needs Docker API access, use a proxy such as `docker-socket-proxy` that restricts which API endpoints are reachable, rather than mounting the raw socket.