Understand permission requirements for Docker Desktop on Mac
Page options
Page options
This page contains information about the permission requirements for running and installing Docker Desktop on Mac.
It also provides clarity on running containers as root
as opposed to having root
access on the host.
Docker Desktop on Windows is designed with security in mind. Administrative rights are only required when absolutely necessary.
Permission requirements
Docker Desktop for Mac is run as an unprivileged user. However, Docker Desktop requires certain functionalities to perform a limited set of privileged configurations such as:
- Installing symlinks in
/usr/local/bin
. - Binding privileged ports that are less than 1024. Although privileged ports (ports below 1024) are not typically used as a security boundary, operating systems still prevent unprivileged processes from binding to them which breaks commands like
docker run -p 127.0.0.1:80:80 docker/getting-started
. - Ensuring
localhost
andkubernetes.docker.internal
are defined in/etc/hosts
. Some old macOS installs don't havelocalhost
in/etc/hosts
, which causes Docker to fail. Defining the DNS namekubernetes.docker.internal
allows Docker to share Kubernetes contexts with containers. - Securely caching the Registry Access Management policy which is read-only for the developer.
Privileged access is granted during installation.
The first time Docker Desktop for Mac launches, it presents an installation window where you can choose to either use the default settings, which work for most developers and requires you to grant privileged access, or use advanced settings.
If you work in an environment with elevated security requirements, for instance where local administrative access is prohibited, then you can use the advanced settings to remove the need for granting privileged access. You can configure:
- The location of the Docker CLI tools either in the system or user directory
- The default Docker socket
- Privileged port mapping
Depending on which advanced settings you configure, you must enter your password to confirm.
You can change these configurations at a later date from the Advanced page in Settings.
Installing symlinks
The Docker binaries are installed by default in /Applications/Docker.app/Contents/Resources/bin
. Docker Desktop creates symlinks for the binaries in /usr/local/bin
, which means they're automatically included in PATH
on most systems.
You can choose whether to install symlinks either in /usr/local/bin
or $HOME/.docker/bin
during installation of Docker Desktop.
If /usr/local/bin
is chosen, and this location is not writable by unprivileged users, Docker Desktop requires authorization to confirm this choice before the symlinks to Docker binaries are created in /usr/local/bin
. If $HOME/.docker/bin
is chosen, authorization is not required, but then you must
manually add $HOME/.docker/bin
to your PATH.
You are also given the option to enable the installation of the /var/run/docker.sock
symlink. Creating this symlink ensures various Docker clients relying on the default Docker socket path work without additional changes.
As the /var/run
is mounted as a tmpfs, its content is deleted on restart, symlink to the Docker socket included. To ensure the Docker socket exists after restart, Docker Desktop sets up a launchd
startup task that creates the symlink by running ln -s -f /Users/<user>/.docker/run/docker.sock /var/run/docker.sock
. This ensures the you aren't prompted on each startup to create the symlink. If you don't enable this option at installation, the symlink and the startup task is not created and you may have to explicitly set the DOCKER_HOST
environment variable to /Users/<user>/.docker/run/docker.sock
in the clients it is using. The Docker CLI relies on the current context to retrieve the socket path, the current context is set to desktop-linux
on Docker Desktop startup.
Binding privileged ports
You can choose to enable privileged port mapping during installation, or from the Advanced page in Settings post-installation. Docker Desktop requires authorization to confirm this choice.
Ensuring localhost
and kubernetes.docker.internal
are defined
It is your responsibility to ensure that localhost is resolved to 127.0.0.1
and if Kubernetes is used, that kubernetes.docker.internal
is resolved to 127.0.0.1
.
Installing from the command line
Privileged configurations are applied during the installation with the --user
flag on the
install command. In this case, you are not prompted to grant root privileges on the first run of Docker Desktop. Specifically, the --user
flag:
- Uninstalls the previous
com.docker.vmnetd
if present - Sets up symlinks
- Ensures that
localhost
is resolved to127.0.0.1
The limitation of this approach is that Docker Desktop can only be run by one user-account per machine, namely the one specified in the -–user
flag.
Privileged helper
In the limited situations when the privileged helper is needed, for example binding privileged ports or caching the Registry Access Management policy, the privileged helper is started by launchd
and runs in the background unless it is disabled at runtime as previously described. The Docker Desktop backend communicates with the privileged helper over the UNIX domain socket /var/run/com.docker.vmnetd.sock
. The functionalities it performs are:
- Binding privileged ports that are less than 1024.
- Securely caching the Registry Access Management policy which is read-only for the developer.
- Uninstalling the privileged helper.
The removal of the privileged helper process is done in the same way as removing launchd
processes.
$ ps aux | grep vmnetd
root 28739 0.0 0.0 34859128 228 ?? Ss 6:03PM 0:00.06 /Library/PrivilegedHelperTools/com.docker.vmnetd
user 32222 0.0 0.0 34122828 808 s000 R+ 12:55PM 0:00.00 grep vmnetd
$ sudo launchctl unload -w /Library/LaunchDaemons/com.docker.vmnetd.plist
Password:
$ ps aux | grep vmnetd
user 32242 0.0 0.0 34122828 716 s000 R+ 12:55PM 0:00.00 grep vmnetd
$ rm /Library/LaunchDaemons/com.docker.vmnetd.plist
$ rm /Library/PrivilegedHelperTools/com.docker.vmnetd
Containers running as root within the Linux VM
With Docker Desktop, the Docker daemon and containers run in a lightweight Linux
VM managed by Docker. This means that although containers run by default as
root
, this doesn't grant root
access to the Mac host machine. The Linux VM
serves as a security boundary and limits what resources can be accessed from the
host. Any directories from the host bind mounted into Docker containers still
retain their original permissions.
Enhanced Container Isolation
In addition, Docker Desktop supports Enhanced Container Isolation mode (ECI), available to Business customers only, which further secures containers without impacting developer workflows.
ECI automatically runs all containers within a Linux user-namespace, such that root in the container is mapped to an unprivileged user inside the Docker Desktop VM. ECI uses this and other advanced techniques to further secure containers within the Docker Desktop Linux VM, such that they are further isolated from the Docker daemon and other services running inside the VM.