When interacting with Docker on a Linux system, attempting to run Docker commands as a non-root user frequently results in a “permission denied” error.
This typically occurs when trying to connect to the Docker daemon’s communication channel, the Unix socket located at /var/run/docker.sock
.
The specific error message often appears as:
docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post "http://%2Fvar%2Frun%2Fdocker.sock/vX.XX/containers/create": dial unix /var/run/docker.sock: connect: permission denied.
This situation arises when executing commands like docker run hello-world
or docker-compose up
without prefixing them with sudo
. While using sudo
works, it is often desirable or necessary to manage Docker as a regular user. This article details the underlying cause of this permission issue and outlines several methods to grant non-root users the required access.
Why the Permission Error Occurs
The Docker daemon, by default, binds to a Unix socket (/var/run/docker.sock
) rather than a network port for local inter-process communication. This socket file acts as the endpoint for the Docker client (the docker
command-line tool) to send instructions to the Docker daemon.
By default, this Unix socket is owned by the root
user, and its group ownership might also be set to root
or a specific docker
group. Access permissions are typically restricted, preventing users other than root
or members of the owning group from connecting to it.
When a non-root user attempts a Docker command, the client tries to open this socket file for communication. If the user lacks the necessary read/write permissions on the socket file, the operating system denies the connection attempt, leading to the observed error.
Read: How to Fix Cannot connect to the Docker daemon at unix:/var/run/docker.sock
Solutions to Grant Non-Root Access
Several approaches can resolve this permission issue, ranging from adjusting group memberships to modifying file permissions directly.
Primary Solution: Add user to the `docker` Group
The most common and generally recommended method is to add your user account to the `docker` group. The Docker daemon is often configured to grant access to the socket for members of this group.
- Create the `docker` group if it doesn’t exist:
sudo groupadd docker
(Note: On many installations, this group might already exist).
- Add your user to the `docker` group:
Replace `$USER` with your actual username if necessary, although `$USER` typically expands correctly in the shell.sudo usermod -aG docker $USER
The
-aG
flags append the user to the specified group without removing them from other groups. - Apply the new group membership:
Group changes usually require a new login session to take effect. You can achieve this by:- Logging out completely and logging back in.
- Rebooting the system:
sudo reboot
- Using the `newgrp` command to start a new shell session with the updated group list (this might prompt for a password):
newgrp docker
(Note: After running `newgrp`, you might need to exit that specific sub-shell to return to your original session, or just continue working within it).
- Alternatively, initiating a new login shell for your user might work:
su - $USER
- In some cases, restarting the Docker service might suffice, especially if not using Snap:
sudo systemctl restart docker
- If Docker was installed via Snap on Ubuntu:
sudo snap restart docker
- Verify the fix:
Attempt to run a Docker command withoutsudo
:docker run hello-world
If successful, the command should execute without permission errors.
⚠️ Security Consideration: Adding a user to the `docker` group effectively grants them privileges equivalent to root access on the host system. Anyone who can interact with the Docker daemon can potentially escalate privileges. Understand the security implications before using this method, especially in multi-user or production environments.
Read: How to Fix the Docker Error: ‘bind: address already in use’
Addressing Potential Configuration File Issues
If you previously ran Docker commands using sudo
, your user’s Docker configuration directory (~/.docker/
) might have incorrect ownership or permissions. This can cause warnings like WARNING: Error loading config file: /home/#user/.docker/config.json - stat /home/#user/.docker/config.json: permission denied
. To fix this, correct the ownership and permissions:
sudo chown "$USER":"$USER" /home/"$USER"/.docker -R
sudo chmod g+rwx "$HOME/.docker" -R
Replace #USER
with your actual username where applicable.
Alternative: Modify Socket File Permissions (`chmod`)
Directly changing the permissions of the /var/run/docker.sock
file can grant access. However, this is often temporary as the socket file might be recreated with default permissions when the Docker daemon restarts or the system reboots.
- Granting Group Write Access (Recommended if modifying permissions):
If the socket’s group is `docker`, ensure your user is in the `docker` group (as above) and set permissions to `660` (read/write for owner, read/write for group, no access for others).sudo chmod 660 /var/run/docker.sock
- Granting World Write Access (Strongly Discouraged):
Setting permissions to `666` (read/write for owner, group, and others) allows any user on the system to interact with the Docker socket.sudo chmod 666 /var/run/docker.sock
⚠️ Security Risk: This approach is highly insecure as it effectively grants root-level capabilities to potentially any user or process on the system. Avoid using `chmod 666` unless the security implications are fully understood and acceptable for the specific environment (e.g., isolated development machine). Permissions like `660` or `640` are generally safer alternatives if direct permission changes are necessary.
If permission changes are frequently reset, you might need to investigate how the socket is created (e.g., systemd unit files) or apply the change persistently, though automating insecure permissions is not recommended.
Alternative: Change Socket File Ownership (`chown`)
Changing the owner of the socket file to your user grants direct access.
sudo chown $USER /var/run/docker.sock
Similar to `chmod`, this change might be temporary if the Docker daemon recreates the socket file with the default owner (usually `root`) upon restart. This is generally considered safer than `chmod 666` but less robust than the group membership method.
Alternative: Use Access Control Lists (ACLs)
ACLs offer finer-grained control over file permissions.
- Ensure the `acl` package is installed:
sudo apt update && sudo apt install acl # Debian/Ubuntu example
- Set read/write permissions for your specific user on the socket:
sudo setfacl -m user:$USER:rw /var/run/docker.sock
Like `chmod` and `chown`, ACLs applied directly to the socket file might not persist if the file is recreated.
Alternative: Modify Systemd Socket Configuration
For systems using systemd, the properties of the Docker socket might be defined in a unit file (e.g., docker.socket
). Modifying this file can potentially make permission or ownership changes persistent across restarts.
The file might be located at /lib/systemd/system/docker.socket
or potentially overridden in /etc/systemd/system/
.
Example modification within the [Socket]
section:
[Socket]
ListenStream=/var/run/docker.sock
SocketMode=0660 # Set permissions (e.g., rw for user and group)
# SocketUser=#YOUR_USERNAME # Optionally set the owner to your user
SocketGroup=docker # Ensure the group is 'docker'
Replace #YOUR_USERNAME
with your actual username if setting the owner. After editing, reload systemd configuration and restart the socket/service:
sudo systemctl daemon-reload
sudo systemctl restart docker.socket
sudo systemctl restart docker.service
⚠️ Note: Modifying systemd unit files requires caution. Incorrect changes can affect service operation. Also, ensure changes align with security best practices (CIS benchmarks suggest `root:root` ownership for the socket file definition itself, though runtime ownership/group might differ based on configuration).
Addressing Systemd Socket Group Ownership
In some cases, particularly after upgrades, the systemd socket unit definition at /lib/systemd/system/docker.socket
might incorrectly have `root:root` ownership or group permissions that prevent the `docker` group from having sufficient rights even if specified in the `SocketGroup` directive. Check its group and permissions:
ls -l /lib/systemd/system/docker.socket
If the group is not `docker` or lacks write permissions needed for group members to connect, you might adjust it (though modifying files in `/lib/systemd/system` is generally less preferred than creating overrides in `/etc/systemd/system`):
# Ensure the group is 'docker'
sudo chgrp docker /lib/systemd/system/docker.socket
# Ensure the group has write permission on the definition (use with caution)
sudo chmod g+w /lib/systemd/system/docker.socket
Potential Conflict with Graphical Logins (LightDM/KWallet)
On some desktop environments using LightDM, a known issue might prevent supplementary group memberships (like being added to the `docker` group) from being correctly applied during graphical login due to interactions with PAM modules like `pam_kwallet`.
If adding the user to the `docker` group doesn’t work despite relogin/reboot, check system logs or bug reports for your distribution (e.g., LightDM bug 1781418). A potential workaround involves commenting out specific `pam_kwallet` lines in `/etc/pam.d/lightdm`, but investigate thoroughly before modifying PAM configurations.
Workaround: Using Aliases
If modifying permissions or group memberships is undesirable due to security policies, creating a shell alias can simplify using `sudo` without granting permanent non-root access to the Docker daemon.
Add the following line to your shell configuration file (e.g., ~/.bashrc
, ~/.zshrc
):
alias docker='sudo docker'
alias docker-compose='sudo docker-compose'
After adding the alias, reload your shell configuration (e.g., source ~/.bashrc
) or open a new terminal. Now, typing docker
or docker-compose
will automatically execute the command with `sudo` (prompting for a password if needed).
Other Considerations
- Is Docker Running? Before troubleshooting permissions, ensure the Docker service is active:
systemctl status docker.service
If inactive, try starting it:
sudo systemctl start docker.service
Investigate logs (`journalctl -u docker.service`) if it fails to start.
- Process Caching (CI/CD Agents): If a long-running process (like a CI/CD agent) was started before Docker permissions were granted, it might retain the old, incorrect permissions. Restarting the agent process after applying permission fixes may be necessary.
- Docker Rootless Mode: For enhanced security, consider running Docker in rootless mode, which allows the daemon and containers to run under a non-root user identity, mitigating certain security risks. Refer to official Docker documentation for setup instructions.
Verification
Regardless of the method chosen, the primary way to verify the fix is to run a Docker command without `sudo`:
docker run hello-world
If the command successfully downloads and runs the test image without any “permission denied” errors related to `docker.sock`, the issue is resolved.
Conclusion
The “permission denied” error when connecting to /var/run/docker.sock
is a common hurdle for users wishing to manage Docker without `sudo`. It stems from standard Unix file permissions restricting access to the Docker daemon’s communication socket. Adding the user to the `docker` group is the most conventional solution, though it carries significant security implications by granting root-equivalent privileges.
Alternatives like adjusting socket permissions/ownership or using ACLs can work but might require repeated application or careful systemd configuration. For security-conscious environments, using aliases or exploring Docker’s rootless mode are viable strategies. Always choose the method that best balances usability and security requirements for your specific context.