Docker is one of the leading platforms for building and running software containers. It comes with everything you need to use containers on either a single host or multiple distributed nodes in Swarm mode.
Docker has a daemon-based architecture. The software that’s responsible for creating and starting containers is independent of the CLI process that accepts your commands. This means you’ll see errors in the CLI if you try to run commands without an active daemon connection. In this article, we’ll share some methods for troubleshooting these frustrating messages.
Problem Symptoms
The Docker CLI is reliant on a daemon connection being available. It interacts with the daemon using API calls. When the configured daemon’s inaccessible, docker
commands like docker ps
, docker run
, and docker build
will show an error message similar to this one:
$ docker run hello-world:latest Cannot connect to the Docker daemon at unix:///var/run/docker.sock Is the docker daemon running?
This reveals that the CLI tried to communicate with the Docker daemon using the /var/run/docker.sock
Unix socket. The socket’s not open so the connection failed.
1. Check the Docker Daemon Service Is Running
The Docker daemon is usually managed by a systemd service that automatically starts Docker after your host reboots. You can begin troubleshooting by checking whether this service is running:
$ sudo systemctl status docker docker.service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled) Active: inactive (dead)
The service should report Active: active (running)
if the daemon is running. The example above shows inactive (dead)
which means the daemon has stopped.
Start Docker using the following command:
$ sudo systemctl start docker
Now you should be able to run docker
CLI commands successfully.
You might find that Docker stays in the stopped state after you reboot your machine. You can solve this by enabling the service, allowing systemd to start it automatically:
$ sudo systemctl enable docker $ sudo systemctl daemon-reload
The daemon-reload
command instructs systemd to reload its configuration to apply the change.
2. Start the Daemon Manually
You might sometimes use a system that doesn’t have the Docker service installed. You can manually start the Docker daemon using the dockerd
command. This usually needs to be run as root
.
$ sudo dockerd INFO[2022-06-29T15:12:49.303428726+01:00] Starting up
Docker will remain accessible for as long as the command’s running. Use Ctrl+C to stop the daemon.
3. Checking the CLI Is Targeting the Correct Daemon
Problems can occur when the CLI is trying to connect to a remote Docker daemon instance. This is usually the cause when the error message shows a TCP address:
$ docker run hello-world:latest Cannot connect to the Docker daemon at tcp:///0.0.0.0:2375
In this example, the docker
CLI is trying to contact the Docker daemon at 0.0.0.0:2375
using TCP, instead of the local Unix Docker socket. This will fail if the Docker daemon’s TCP support is disabled or the specified host is inaccessible on the network.
You can usually resolve this by switching to the correct Docker CLI context for the daemon connection you want to use:
$ docker context use default
You can list all the available contexts and the daemon endpoints they connect to with the context ls
command:
$ docker context ls NAME DESCRIPTION DOCKER ENDPOINT default * Current DOCKER_HOST based configuration unix:///var/run/docker.sock
The currently selected context is highlighted with an asterisk.
Unexpected values in the DOCKER ENDPOINT
column are usually caused by the DOCKER_HOST
environment variable being set. You’ll see a warning when this is the case:
$ export DOCKER_HOST=1.2.3.4 $ docker context ls NAME DESCRIPTION DOCKER ENDPOINT default * Current DOCKER_HOST based configuration tcp://1.2.3.4:2375 Warning: DOCKER_HOST environment variable overrides the active context. To use a context, either set the global --context flag, or unset DOCKER_HOST environment variable.
The presence of the DOCKER_HOST
environment variable in your shell overrides the endpoint defined by your selected context. In this example, docker
commands will always target the daemon instance at tcp://1.2.3.4:2375
.
This problem can be resolved by clearing the DOCKER_HOST
variable:
$ export DOCKER_HOST=
Docker will now use the endpoint configured by your active context. This will be the default local Unix socket at /var/run/docker.sock
unless you’ve manually set up a custom context.
$ docker context ls NAME DESCRIPTION DOCKER ENDPOINT default * Current DOCKER_HOST based configuration unix:///var/run/docker.sock
4. Permissions Issues
Incorrect user permissions on Docker’s socket are another common cause of daemon connection issues. This kind of problem usually shows a slightly different error message:
$ docker run hello-world:latest Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock
This happens when your Unix user account lacks permission to interact with the socket that exposes the Docker API. Adding yourself to the docker
group is the best practice way to resolve this problem:
$ sudo usermod -aG docker $USER
You’ll need to open a new shell window or logout and back in again for this change to take effect. You should now be able to run docker
commands without running into permissions problems.
Summary
“Cannot connect to the Docker daemon” appears when the Docker CLI is unable to communicate with a Docker daemon instance using your current configuration. This is often because the Docker daemon service has been stopped or disabled. You could also be trying to connect to a remote Docker host that’s gone offline.
You should now be aware of the possible causes of this problem and the common ways to solve it. Troubleshoot the error by checking your Docker daemon settings, restarting the Docker service, and making sure your user account has permission to interact with Docker’s socket.