Recent Posts


Accessing Docker Desktop’s Virtual Machine


Frustrated by Magento? Then you’ll love Commerce Bug, the must have debugging extension for anyone using Magento. Whether you’re just starting out or you’re a seasoned pro, Commerce Bug will save you and your team hours everyday. Grab a copy and start working with Magento instead of against it.

Updated for Magento 2! No Frills Magento Layout is the only Magento front end book you'll ever need. Get your copy today!

Containers (in the modern sense) are a technology that allows you to run Linux processes that are isolated from one another.

Docker is an American corporation that builds platform software to help users work with Linux containers.

One piece of software provided by Docker Inc. is Docker Desktop, which will allow you to run Docker container images on non-Linux computers.

Docker Desktop does not run processes directly on your Mac or Windows machine — instead Docker Desktop provides a virtual machine that runs Linux, and when you ask Docker to run a command it will run that command on this virtual machine.

This is useful technology and makes Docker available to most working programmers. However, it can be hard to watch what, exactly, your containers are doing when you have this extra layer of virtualization in the middle of things.

There are a few ways to work around this problem that, like everything these days, are archived in a gist created by a random friendly human.

First, Docker makes a debugging socket available that gives us access to a shell inside the Linux virtual machine where your containers are running. On macOS, we can find the debugging socket at


The most universal way of using this shell is with the program netcat

% nc -U ~/Library/Containers/com.docker.docker/Data/debug-shell.sock
/ # ^[[23;5R

You’ll get a really weird looking prompt, but you should be able to run commands.

/ # ^[[23;5Rps aux | grep docker
ps aux | grep docker
 1108 root      1:51 /usr/bin/containerd-shim-runc-v2 -namespace services.linuxkit -id docker -address /run/containerd/containerd.sock
 1131 root      0:57 /usr/bin/docker-init /usr/bin/
 1411 root      0:01 /usr/bin/trim-after-delete -- /sbin/fstrim /var/lib/docker
 1669 root      0:01 /usr/bin/logwrite -n dockerd /usr/local/bin/dockerd --containerd /var/run/desktop-containerd/containerd.sock --pidfile /run/desktop/ --config-file /run/config/docker/daemon.json --swarm-default-advertise-addr=eth0 --host-gateway-ip
 1674 root      5:17 /usr/local/bin/dockerd --containerd /var/run/desktop-containerd/containerd.sock --pidfile /run/desktop/ --config-file /run/config/docker/daemon.json --swarm-default-advertise-addr=eth0 --host-gateway-ip
 5933 root      0:00 grep docker

When you use netcat you’re issuing commands directly to the socket without any of the usual nice features (a reasonable command prompt, shell history, etc) that come along with a modern shell environment. Running one of the following commands will get you a much nicer shell experience

% docker run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh

% docker run -it --rm --privileged --pid=host justincormack/nsenter1

The first command runs the Linux program nsenter, which is a command that will let you run a specific Linux program in a specific process namespace. This command uses the Docker Hub Debian image to run nsenter (which is part of a stock Debian install) and nsenter is running the sh shell.

The second command is running the justincormack/nsenter1 container (Docker Hub and repo). The justincormack/nsenter1 container has a build of a nsenter like program that allows you to omit all those arguments. The Dockerfile is an interesting one — it uses alpine Linux to compile the nsenter1 program, and then adds nsenter1 to a FROM scratch image.

Both of these docker run invocations don’t (appear to?) use the debugging socket. Instead the magic is in “--pid=host“, which tells Docker to run the command in the process space of the host OS, which for Docker Desktop will be the virtual machine where these commands run. (also notice that Docker uses the language of VMs here (“host” OS)).

If you don’t quite follow that, don’t worry, you don’t need to. (I only vaguely grasp the implications). All you need to know is you can get a shell into your Docker Desktop VM by running the following

% docker run -it --rm --privileged --pid=host justincormack/nsenter1

and then poke around your Linux machine. For example, if you wanted to see how Docker stores all the layers for its container images you’d just

% docker run -it --rm --privileged --pid=host justincormack/nsenter1 
/ # ls /var/lib/docker/overlay2/
Series Navigation<< Five Reasons Your PHP Application is Hard to Containerize for Production

Copyright © Alana Storm 1975 – 2023 All Rights Reserved

Originally Posted: 2nd January 2023

email hidden; JavaScript is required