129

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.

1
  • 2
    "a container is set of virtualized processes" or also jailed processes -- which may be a little bit less abstract. Commented Mar 5, 2018 at 19:03

12 Answers 12

117

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> 
Sign up to request clarification or add additional context in comments.

5 Comments

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.
The container is not a process in the host machine
@RaulLapeiraHerrero I'm pretty sure he actually meant the PID of the processes running in the container from the host machine perspective JohannesGehrs answer does answer perfectly, in my opinion.
Yea, probably he is asking that, I was more focused in denying this answer than promoting the other... talking about negative thinking xd
@RaulLapeiraHerrero container is a process in the host machine.
67

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.

3 Comments

This is the best answer, and it is a solution for a known issue with no solution: 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.
Are the docker containers listed under docker? In Docker version 18.09.4, systemd lists containers under containerd.service not docker.service
I have been using containers for "some time" XD and I don't find a useful scenario for this
37

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 

2 Comments

extremely useful and clean solution
Thanks for this solution! Xargs works faster: docker container ls --format "{{.ID}}" | xargs docker inspect -f '{{.State.Pid}} {{.Name}}'
23

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 

6 Comments

Thanks @Thomasleveil
If a visual tree is enough you can also use ps -axfo pid,ppid,uname,cmd
I was wondering what is the purpose of "keeping only processes that parent process ID is the one of the docker daemon"? The only child of dockerd process is docker-proxy. The containers are not shows as descendants of dockerd process.
@Tim this answer is more than 3 years old, things might have changed
It's not a good idea to rely on internal implementation details (i.e. some internal process name that may change at any time). The other answers are much better since they use documented APIs
|
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 

1 Comment

does not work on my server. however systemd-cgls works
4

docker ps will list docker containers that are running.

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

3 Comments

This will present processes from container point of view i want to find processes from host point of view and for more misunderstandings i will edit the question.
I would suggest including an example of why - because typically, there isn't much need.
Process migration tests
4

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 

2 Comments

it's not working cat: /proc/80300: Is a directory Usage: grep [OPTION]... PATTERNS [FILE]... Try 'grep --help' for more information.
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
4

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 

2 Comments

This is really good. The systemd-cgls solution did what I wanted, and is certainly easier, but this has the advantage of naming the containers. With systemd-cgls, I still needed to analyze all the processes in the container to figure out which container it was.
The output is somehow duplicated. I've created an alternative script to address that: for i in $(docker container ls --format "{{.ID}}|{{.Names}}|{{.Image}}"); do printf $i | awk -F '|' '{str = sprintf("----\ncontainer_name: %s, image_name: %s", $2, $3)} END {print str}'; printf $i | cut -d '|' -f 1 | xargs -n1 docker inspect -f '{{.State.Pid}}' | sed '/PID/d' | xargs -n1 pstree -palc; done
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 {} 

Comments

0

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.

Comments

0

You can exec any command you like from within your container, and so use all usual command for process monitoring :

docker exec [container_id | container_name] [command executed inside container] 

To get container id or name you can use :

docker ps 

Some examples if container id is "a069585a80cb " :

docker exec a069585a80cb top docker exec a069585a80cb ps docker exec a069585a80cb watch ps docker exec a069585a80cb watch "ps aux | head -10" ... 

NB: using name of the container rather than its id, may be better choice for scripting as container id may often change

Comments

-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/

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.