Docker "Permission Denied" on docker.sock: Safe Fix

Docker "permission denied" on docker.sock means your user isn't allowed to use the Docker socket. Join the docker group and log back in, or use rootless Docker.
The full error looks like this: permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock. You see it the first time you run docker ps without sudo on a new server, and again when a CI runner, Jenkins or a deploy user tries to build images. The internet's favourite fix, sudo chmod 666 /var/run/docker.sock, works and is the worst choice: it gives every user and process on the machine root access. I run Docker on servers where a non-root deploy user ships releases, so here are the fixes I actually use and what each one costs you in security.
Key takeaways
- The socket is owned by
root:dockerwith mode 660. Only root and members of thedockergroup can talk to the daemon. - The standard fix is
sudo usermod -aG docker $USER, then log out and back in. Group changes don't apply to sessions that are already open. - The docker group is root-equivalent. Docker's own docs say so: anyone in it can mount the host filesystem into a container.
- Rootless Docker runs the daemon as your user, so a container escape doesn't hand out root. It's the safer choice on shared machines.
- Never
chmod 666the socket. It hands root to every local user, and it resets on reboot anyway.
Step 1: Make sure it's a permission problem
Two errors look similar but have different fixes:
- "permission denied while trying to connect to the Docker daemon socket": the daemon is running, your user just isn't allowed to use it. Keep reading.
- "Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?": the daemon is stopped or crashed. Check
sudo systemctl status dockerandsudo journalctl -u docker -n 50.
Then look at the socket and at your groups:
ls -l /var/run/docker.sock # srw-rw---- 1 root docker 0 Oct 7 09:12 /var/run/docker.sock id # uid=1000(deploy) gid=1000(deploy) groups=1000(deploy),27(sudo)
If docker isn't in the list from id, that's the whole problem.
Fix 1: Add your user to the docker group
This is the method in Docker's post-install guide:
sudo groupadd docker # usually exists already; an error here is fine sudo usermod -aG docker $USER newgrp docker # applies to this shell only docker run --rm hello-world
The -a matters: without it, usermod -G replaces all your other groups, including sudo. If it still says permission denied, your session predates the change. Log out and back in; for SSH, close the connection and reconnect. Three places keep the old groups longer than people expect:
- tmux and screen sessions started before the change. Start a new session.
- VS Code Remote-SSH keeps a server process running. Use "Kill VS Code Server on Host" and reconnect.
- Services such as a GitHub Actions self-hosted runner or Jenkins only pick up new groups after a restart:
sudo usermod -aG docker jenkins && sudo systemctl restart jenkins.
Why the docker group is effectively root
The daemon runs as root, and the socket is its full control API. Anyone who can reach it can run this:
docker run --rm -it -v /:/host alpine chroot /host sh # a root shell on the host
That's not a bug, it's how Docker works, and Docker's docs warn that the group "grants root-level privileges". So treat membership like sudo without a password: give it only to people and service accounts you'd trust with root. On a single-purpose server where your deploy user already has sudo, the docker group adds little risk. On a shared machine or a CI runner that builds untrusted pull requests, prefer rootless mode.
Fix 2: Rootless Docker
Rootless mode runs a separate Docker daemon as your own user, inside a user namespace. A process that breaks out of a container lands as your unprivileged user, not root. On Ubuntu with Docker's official packages:
sudo apt-get install -y uidmap docker-ce-rootless-extras dockerd-rootless-setuptool.sh install systemctl --user enable --now docker sudo loginctl enable-linger $USER # keep it running after you log out export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock docker run --rm hello-world
Put the DOCKER_HOST line in your ~/.bashrc, or use docker context use rootless. Trade-offs to know before switching: images and containers live in your home directory, separate from the root daemon's; binding ports below 1024 needs extra setup (proxy 80/443 from Nginx on the host instead); and some networking and resource-limit features behave differently. The rootless docs list the current limitations.
Fix 3: Keep using sudo
Typing sudo docker is a perfectly good answer for admins on production servers. Every command is logged in the auth log, nobody gets silent root, and you can limit which users have it. For deploy scripts, I prefer a dedicated deploy user in the docker group over giving it general passwordless sudo.
Special cases
A container that mounts docker.sock
Tools like Portainer, Traefik or a CI container mount /var/run/docker.sock and then get permission denied because the docker group ID inside the container differs from the host's. Pass the host's group ID instead of running the container as root:
docker run --group-add "$(stat -c %g /var/run/docker.sock)" \ -v /var/run/docker.sock:/var/run/docker.sock my-ci-image
Remember that whatever you hand the socket to also gets root on the host. A read-only mount doesn't change that, since the API still works. Only mount it into containers you trust, or put a socket proxy in front that allows just the API calls the tool needs.
GitHub Actions self-hosted runners
Add the runner's user to the docker group, then restart the runner service so it picks up the group (sudo ./svc.sh stop && sudo ./svc.sh start in the runner directory). If the runner builds pull requests from forks, use rootless Docker or ephemeral runners instead.
It worked, then broke after a reboot
That's the chmod 666 fix wearing off: Docker recreates the socket with root:docker 660 every time it starts. Use the group instead.
For containers that start and then keep dying, see my Docker restart loop guide. And if you publish container ports on a server with UFW, read why Docker bypasses UFW before you go live.
Frequently asked questions
Why do I still get permission denied after adding myself to the docker group?
Group membership is read when you log in, so existing sessions don't have it. Log out and back in, reconnect SSH, start a new tmux session, or run newgrp docker in the current shell. Check with id that docker appears.
Is it safe to chmod 666 /var/run/docker.sock?
No. It lets every user and process on the machine control a root daemon, which is the same as giving them root. It also resets when Docker restarts. Use the docker group, rootless mode or sudo.
Is adding a user to the docker group a security risk?
Yes, it's equivalent to giving that user root, because they can mount the host filesystem into a container. That's acceptable for trusted admins and deploy users on a single-purpose server, but not for untrusted users or shared machines.
What's the difference between rootless Docker and the docker group?
With the docker group, your user controls a daemon running as root. With rootless Docker, the daemon itself runs as your user, so a container escape only gets your user's permissions. Rootless is safer but has some limits on networking and low ports.
How do I fix Jenkins "permission denied" on docker.sock?
Add the jenkins user to the docker group with sudo usermod -aG docker jenkins and restart Jenkins so it gets the new group. If Jenkins runs in a container, pass the socket's group ID with --group-add.
Want Docker set up safely?
I set up Docker and CI/CD on Linux servers with least-privilege deploy users, firewalls that actually apply to containers, and automated deploys with rollback. See my DevOps services, or contact me with what you're running and the error you see.
Written by
MD Rakibul Islam Rakib
Full-stack developer, DevOps engineer and Linux system administrator with 5+ years of production experience. I deploy, harden and fix servers and web apps for clients worldwide, and everything in this article runs on real servers I manage, including this site.
- docker permission denied
- docker.sock permission denied
- docker group
- rootless Docker
- Cannot connect to the Docker daemon
- Ubuntu
- DevOps


