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/entrypoint.sh 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/docker.pid --config-file /run/config/docker/daemon.json --swarm-default-advertise-addr=eth0 --host-gateway-ip 192.168.65.2 1674 root 5:17 /usr/local/bin/dockerd --containerd /var/run/desktop-containerd/containerd.sock --pidfile /run/desktop/docker.pid --config-file /run/config/docker/daemon.json --swarm-default-advertise-addr=eth0 --host-gateway-ip 192.168.65.2 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
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/ 3f5896f765b32aae99ce5438549cbf63e6b300f98a09a98d65cccd8e2e312e13 3f5896f765b32aae99ce5438549cbf63e6b300f98a09a98d65cccd8e2e312e13-init 3kwa3cw2gqhyyzj9o6klw7nro 8crhoels0omzrfafpmk9xvn6w cb891d75ec97ee49e230d2b99d1313b21cf8f7483bdcc7529c8dbf3d6cf130bb e4feafcb6867b603b9805b1f2a38a93e0d40d5114522205c8e52f8ac02af6eee igluqjpeomstq9zw0mdkgmpad iqqd91k86cr1wygxofzdc4s0x l nmlli3bpts1sfdcsu8v09jygg ri9ymazsv0g54omflyy4z72w7 tbkxsdlbk154vm57rkbiwy0ld vxe4nhs6h1geva8qhukr5qkag zri9zy0m3kfopmb7ux7drsb4g