I seem to be hitting some sort of permissions issue while trying to use unix sockets between my host and a Docker container.
Within a running container, I have a server listening to a unix socket on a mounted volume. When I attempt to connect to the socket from outside the container (using the mounted volume), I get an ECONNREFUSED error. I have verified that what I am talking to is a socket created by the container.
I’m assuming there must be something very basic I am missing here that is preventing this from working.
Some additional information:
- Container running Linux (have also tried ubuntu)
- I am running Mac OS, however my co-worker has the same issue on Linux
- The file seems to have different owners between Docker and my Host (owned by root and my current user, respectively), however both have the
srwxrwxrwx
permissions. - The volume’s directory on my host machine is set in my
Resources > File Sharing
settings in Docker Desktop - Our Docker Compose file has given explicitly read-write permissions to the volume.
- If I call the socket from within the container, it works as expected.
I’ve read pretty much the entire reference for volumes in Docker Compose, I’ve read pretty much every tutorial and Stack Overflow post on the topic, and it still seems to persist.
Any ideas on why this might not be working would be greatly appreciated!
2
Answers
There might be different reasons, but most probably:
Check if you use host networking mode for your Docker container
Disable SELinux or AppArmor modules in Linux or configure them to allow the socket communication.
you can check if SELinux is blocking socket communications
/var/log/audit/audit.log
, if it is blocking, create custom policy module to allow it.Also, While the socket permission is srwxrwxrwx, but You could try to change the owner of the socket file or add your user to the docker group
Hope that help!
You will never be able to share a Unix socket between a container and a host on any setup using Docker Desktop, or any other VM-based Docker implementation. I’d only expect it to work on native Linux directly using the Docker engine without Docker Desktop.
Unix sockets essentially work by the kernel relaying data from the writer to the reader. If the two processes aren’t using the same kernel, they won’t be able to share a Unix socket. (Another classic example is two systems sharing an NFS mount; even if the socket file is visible to both systems, they can’t actually use it to communicate.)
On all operating systems – even Linux – Docker Desktop works by starting a hidden Linux virtual machine, running a Docker daemon inside that VM, and relaying Docker API requests and TCP connections for published ports to the VM. That means the containers are using the VM’s kernel, which in turn means that host processes are not using the same kernel, and so Unix sockets won’t work.
The Docker socket
/var/run/docker.sock
is a special case. You needdocker
commands on the host to affect the Docker daemon inside the container, and recipes that bind-mount the host’sdocker.sock
are very common. The Docker Desktop application provides its own Unix socket listener (though usually in the user’s home directory) and relays it into the VM. Bind-mounting the socket into a container actually bind-mounts it from the VM filesystem, where it’s in the normal place.