permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock:
Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.47/containers/json": dial unix /var/run/docker.sock: connect: permission denied
The docker command talks to the Docker daemon through a Unix socket, /var/run/docker.sock. The socket is owned by root and the docker group, so a regular user who is in neither can’t use it. There are three ways to fix it — choose deliberately, because they have different security implications.
Check the socket and your groups
ls -l /var/run/docker.sock
# srw-rw---- 1 root docker 0 Nov 4 09:00 /var/run/docker.sock
id
# uid=1000(alice) gid=1000(alice) groups=1000(alice),27(sudo)
If docker isn’t in your groups, that’s the cause.
Fix 1: use sudo
sudo docker ps
Simple and explicit — every Docker action is visibly privileged and logged by sudo. Fine for occasional use.
Fix 2: add your user to the docker group
sudo usermod -aG docker $USER
Group membership is read at login, so the change doesn’t apply to your current session. Either:
- log out and back in (for SSH, disconnect and reconnect), or
- start a shell with the new group:
newgrp docker.
Then:
docker ps
If it still fails after re-logging in, check id again — some environments (tmux sessions started earlier, VS Code remote servers, systemd user services) keep the old group list until they’re restarted too.
If the docker group doesn’t exist (unusual with official packages), create it and restart Docker:
sudo groupadd docker
sudo usermod -aG docker $USER
sudo systemctl restart docker
The security trade-off
Anyone in the docker group can run:
docker run -v /:/host -it debian chroot /host
…and get a root shell on the host. Docker group membership is equivalent to root access. Only add trusted administrators, never service accounts of web apps, and never “fix” the error by making the socket world-writable.
Fix 3: rootless Docker
Rootless mode runs the Docker daemon itself as your user, so neither the daemon nor the containers have root privileges on the host:
sudo apt-get install -y uidmap docker-ce-rootless-extras
dockerd-rootless-setuptool.sh install
The setup tool prints environment variables to add to your shell profile, typically:
export DOCKER_HOST=unix:///run/user/1000/docker.sock
Enable it to run without an active login:
systemctl --user enable --now docker
sudo loginctl enable-linger $USER
Limitations: binding ports below 1024 requires extra configuration, some storage drivers and network features differ, and performance of port forwarding can be lower. See rootless Docker for details.
Don’t do this
sudo chmod 666 /var/run/docker.sock # NO
It makes the socket — and root on your server — available to every user and every process, including a compromised web app. It also resets when Docker restarts, so it doesn’t even “work” reliably.
Other causes of the same error
Docker isn’t running. Then the message is usually “Cannot connect to the Docker daemon”, but check anyway:
systemctl status docker
Wrong DOCKER_HOST. A leftover environment variable (for example from a rootless setup or a remote context) points the CLI elsewhere:
echo $DOCKER_HOST
docker context ls
docker context use default
Inside a container (Docker-in-Docker, CI runners). When you mount /var/run/docker.sock into a container, the user inside must have the socket’s group ID. Find the GID on the host with stat -c %g /var/run/docker.sock and pass it with --group-add <gid>.
Snap-installed Docker. The snap version uses a different socket path and group handling; consider removing it and installing from Docker’s apt repository.
Which fix should you use?
- Personal server, you’re the only admin: the
dockergroup is the convenient standard. - Shared server or compliance requirements: keep using
sudo, or use rootless Docker. - CI runners: dedicated VMs per runner, or rootless/Podman — avoid sharing a privileged socket between untrusted jobs.
Back to basics: installing Docker on Ubuntu, or read about Docker security best practices.