Manage container process from host
A running Docker container is just a process, isolated from the host and other containers using Linux kernel features, such as namespaces and cgroups. This is one of the main differentiators between VMs and containers.
When you start a Docker container, Docker creates a new process in the host system’s process tree. Then it will apply the container’s configuration such as its file system, network settings and so on to this process.
This makes the host OS consider a Docker container as just another process running on the system. Since the container is running as a process, we can actually use standard process monitoring tools, such as ps
and top
, to view the running container.
This post will examine how to find and access a container’s process ID (PID) and root filesystem directly from the host.
Spin up an Nginx container
docker run -d --name nginx nginx:latest
Access container PID
Docker stores information about the container, including its image, configuration, volume, process ID, and network, in a low-level JSON object. You can use the docker inspect
to view this object. One way to do it is to pipe the output to jq
and parse the JSON object as you wish, or query a scalar element by its name using Go lang template syntax, as follows:
# SYNTAX: docker inspect -f '{{.State.Pid}}' <CONTAINER_ID|CONTAINER_NAME>
docker inspect -f '{{.State.Pid}}' nginx
Check the /proc
directory
In Linux, the /proc
directory is a virtual file system that provides a view of the system’s running processes. It contains files and directories that are dynamically generated by the kernel to provide information about the processes.
Each process running on the system has its own subdirectory under /proc
, identified by its process ID (PID). For example, if you have a process id = 12345, you’d find its subdirectory in this path: /proc/12345
. Inside this subdirectory, you can find various files that provide information about the process, such as its memory usage, file descriptors, and more.
So, since the Nginx container that we spun up previously is just a process, we should see a directory named after its PID in /proc
.
Let’s re-run the above command and assign the output to a variable, and check its proc
directory:
PID=$(docker inspect -f '{{.State.Pid}}' nginx)
ls /proc/$PID
Now let’s inspect the container’s “root” filesystem /proc/$PID/root
:
ls /proc/$PID/root
bin dev docker-entrypoint.sh home lib64 mnt proc run srv tmp var
boot docker-entrypoint.d etc lib media opt root sbin sys usr
If we exec
into the container, we can see the same content from inside the container:
docker exec -it nginx
root@ed08325bda2d:/# ls
bin dev docker-entrypoint.sh home lib64 mnt proc run srv tmp var
boot docker-entrypoint.d etc lib media opt root sbin sys usr
Manipulate the container process
Like any process on the host, you can control it, but with some limitations. You can see below how the container was terminated using the kill
command without interacting with the Docker daemon:
ps aux | grep $PID
root 8929 0.0 0.0 8936 5872 ? Ss 11:30 0:00 nginx: master process nginx -g daemon off;
root 9053 0.0 0.0 17864 2408 pts/4 S+ 11:31 0:00 grep --color=auto 8929
List the containers:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
522e39dfc08e nginx "/docker-entrypoint.…" 10 minutes ago Up 7 minutes 80/tcp nginx
Kill the container PID without using Docker daemon:
kill -9 $PID
Check again:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES