106

I am doing some tests on docker and containers and I was wondering:

Is there a method I can use to find all process associated with a docker container by its name or ID from the host point of view.

After all, at the end of the day a container is a set of virtualized processes.

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
Walid Hanafy
  • 1,429
  • 2
  • 14
  • 26

11 Answers11

106

You can use docker top command. This command lists all processes running within your container.

For instance this command on a single process container on my box displays:

UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                14097               13930               0                   23:17               pts/6               00:00:00            /bin/bash

All methods mentioned by others are also possible to use but this one should be easiest.

Update:

To simply get the main process id within the container use this command:

 docker inspect -f '{{.State.Pid}}' <container id>
Boynux
  • 5,958
  • 2
  • 21
  • 29
  • This doesn't answer the question - `docker top` is showing PIDs of processes running within the container, from the container's pid namespace. This user is asking for the PID of the container, from the host's perspective. – vincebel Jul 18 '23 at 17:17
51

Another way to get an overview of all Docker processes running on a host is using generic cgroup based systemd tools.

systemd-cgls will show all our cgroups and the processes running in them in a tree-view, like this:

├─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 21
├─docker
│ ├─070a034d27ed7a0ac0d336d72cc14671584cc05a4b6802b4c06d4051ce3213bd
│ │ └─14043 bash
│ ├─dd952fc28077af16a2a0a6a3231560f76f363359f061c797b5299ad8e2614245
│ │ └─3050 go-cron -s 0 0 * * * * -- automysqlbackup

As every Docker container has its own cgroup, you can also see Docker Containers and their corresponding host processes this way.

Two interesting properties of this method:

  1. It works even if the Docker Daemon(s) are defunct.
  2. It's a pretty quick overview.

You can also use systemd-cgtop to get an overview of the resource usage of Docker Containers, similar to top.

By the way: Since systemd services also correspond to cgroups these methods are also applicable to non-Dockerized systemd services.

Johannes Gehrs
  • 722
  • 6
  • 13
  • 2
    This is the best answer, and it is a solution for a known issue with no solution: https://github.com/moby/moby/issues/12738 . User needs to (1) find the pid id of the docker process, most easily identified by the port number associated with the container, and (2) find the pid of the associated containerid hash, and kill both. Thanks for this tip. – truedat101 Apr 05 '19 at 07:08
  • 2
    Are the docker containers listed under `docker`? In Docker version 18.09.4, systemd lists containers under `containerd.service` not `docker.service` – Tim Apr 06 '19 at 22:18
28

I found a similar solution using a bash script in one line:

for i in $(docker container ls --format "{{.ID}}"); do docker inspect -f '{{.State.Pid}} {{.Name}}' $i; done
user3788120
  • 447
  • 4
  • 4
24

the process run in a docker container is a child of a process named containerd-shim (in Docker v18.09.4)

  • First figure out the process IDs of the containerd-shim processes.
  • For each of them, find their child process.

pgrep containerd-shim
7105
7141
7248

To find the child process of parent process 7105:

pgrep -P 7105

7127


In the end you could get the list with:

for i in $(pgrep containerd-shim); do pgrep -P $i; done
7127
7166
7275
Thomasleveil
  • 95,867
  • 15
  • 119
  • 113
6

When running this on the host, it will give you a list of processes running in a container with <Container ID>, showing host PIDs instead of container PIDs.

DID=$(docker inspect -f '{{.State.Pid}}' <Container ID>);ps --ppid $DID -o pid,ppid,cmd
Beam
  • 69
  • 1
  • 3
5

docker ps will list docker containers that are running.

docker exec <id|name> ps will tell you the processes it's running.

Sobrique
  • 52,974
  • 7
  • 60
  • 101
2

Since the following command shows only the container's itself process ID (not all child processes):

docker inspect -f '{{.State.Pid}}'  <container-name_or_ID>

To find a process that is the child of a container, this process ID must be find in directory /proc. So find "processID" inside it and then find the container hash from file:

/proc/parent_process/task/processID

and then cut container ID from hash (first 12-digits of the container hash) and then find the container itself:

#!/bin/bash 
processPath=$(find /proc/ -name $1 2>/dev/null) 
containerID=$(cat ${processPath}/cgroup | fgrep 'pids:/docker/' | sed -e 's#.*/docker/##g' | cut -c 1-12) 
docker ps | fgrep $containerID

Save above script in a file such as: p2c and run it by:

p2c <PID>

For example:

p2c 85888
halfer
  • 19,824
  • 17
  • 99
  • 186
Mohsen Abasi
  • 2,050
  • 28
  • 30
  • it's not working cat: /proc/80300: Is a directory Usage: grep [OPTION]... PATTERNS [FILE]... Try 'grep --help' for more information. – Bogdan Mart Sep 07 '21 at 22:01
  • Try: `processPath=$(find /proc/ -name $1 2>/dev/null | tail -n1); containerID=$(cat ${processPath}/cgroup | egrep 'docker.*\.scope' -o | cut -c 8-19); docker ps | fgrep $containerID;` instead – Anonymous Mouse Jul 23 '22 at 13:00
1

There are scenarios where the docker service on the container itself becomes unresponsive, so docker inspect stops responding. If that happens, you can use procps to search for your container's PID. You can easily list all containers launched with docker run like this (you might need to match a different pattern if you are using compose or another orchestration framework):

ps aux | grep 'docker run'

Then you can kill your container with kill -9 <container_pid> (SIGKILL) You will also need to restart docker daemon (IE service docker restart) after doing this for it to "deregister" your container.

ThisGuyCantEven
  • 1,095
  • 12
  • 21
1

Building on @zangw's work, I wanted the container name and image as well. (pstree can be found by installing psmisc)

for i in $(docker container ls --format "{{.ID}}|{{.Names}}|{{.Image}}"); do printf $i | awk -F '|' '{str = sprintf("%s %s %s %s", "conatiner_name: ", $2, "| image_name:", $3)} END {print str}'; printf $i | awk -F '|' '{print $1}' | xargs -I'{}' docker top {} -o pid | awk '!/PID/' | xargs -I'{}' pstree -psa {}; done

or will pipe to less (/myterm to search + enter, then 'n' for next entry and 'N' for previous entry.)

for i in $(docker container ls --format "{{.ID}}|{{.Names}}|{{.Image}}"); do printf $i | awk -F '|' '{str = sprintf("%s %s %s %s", "conatiner_name: ", $2, "| image_name:", $3)} END {print str}'; printf $i | awk -F '|' '{print $1}' | xargs -I'{}' docker top {} -o pid | awk '!/PID/' | xargs -I'{}' pstree -psa {}; done | less

Sample output on CentOS 7:

conatiner_name:  myproject_chrome_1 | image_name: selenium/standalone-chrome:4.5.2-20221021
    systemd,1 --switched-root --system --deserialize 22
      `-containerd-shim,24700 -namespace moby -id d22cd987862ed0d7c09431d12e2c8e4061f688a3401d1c1188458cbabe11a324 -address/run/
          `-bash,24727 /opt/bin/entry_point.sh
              `-supervisord,24828 /usr/bin/supervisord --configuration /etc/supervisord.conf
                  |-bash,24924 /opt/bin/start-xvfb.sh
                  |   `-xvfb-run,24933 /usr/bin/xvfb-run --server-num=99 --listen-tcp...
                  |       |-Xvfb,24964 :99 -screen 0 1360x1020x24 -fbdir /var/tmp -dpi 96 -listen tcp -noreset -ac +extension RANDR ...
                  |       `-fluxbox,25023 -display :99.0
                  |-bash,24925 /opt/bin/start-vnc.sh
                  |   `-x11vnc,25134 -usepw -forever -shared -rfbport 5900 -rfbportv6 5900 -display :99.0
                  |-bash,24926 /opt/bin/start-novnc.sh
                  |   `-bash,24932 /opt/bin/noVNC/utils/launch.sh --listen 7900 --vnc localhost:5900
                  |       `-python3,24955 -m websockify --web /opt/bin/noVNC/utils/../ 7900 localhost:5900
                  `-bash,24927 -c /opt/bin/start-selenium-standalone.sh && kill -s SIGINT `cat /var/run/supervisor/supervisord.pid`
                      `-bash,24928 /opt/bin/start-selenium-standalone.sh
                          `-java,25037 -Dwebdriver.http.factory=jdk-http-client -jar /opt/selenium/selenium-server.jar --ext...
                              |-{java},25058
                              |-{java},25060
Joshua Graham
  • 268
  • 1
  • 5
0

Another solution with docker container and docker top

docker ps --format "{{.ID}}" | xargs -I'{}' docker top {} -o pid | awk '!/PID/'

Note: awk '!/PID/' just remove the PID header from the output of docker top


If you want to know the whole process tree of docker container, you can try it

docker ps --format "{{.ID}}" | xargs -I'{}' docker top {} -o pid | awk '!/PID/' | xargs -I'{}' pstree -psa {}
zangw
  • 43,869
  • 19
  • 177
  • 214
-4

Docker stats "container id" Shows the resource consumption along with pid or simply Docker ps .

Probably this cheat sheet can be of use. http://theearlybirdtechnology.com/2017/08/12/docker-cheatsheet/