docker find container by pid of inside process - docker

I have docker containers. Inside them launched a process.
From the host machine the command top outputs pid of all processes launched in within containers.
How can I find a container in which the process with this PID is running?
Thank you.

Thank you #Alex Past and #Stanislav for the help. But I did not get full answers for me. I combined them.
In summary I has got next.
First
pstree -sg <PID>
where PID is the process's PID from the command top
In output I am getting parent PID for the systemd parent process. This PID is docker container's PID.
After I execute
docker ps -q | xargs docker inspect --format '{{.State.Pid}}, {{.Name}}' | grep "^%PID%"
where %PID% is this parent PID.
In result I have docker's CONTAINER ID.
That's what I wanted

I suppose you need something like this:
docker ps -q | xargs docker inspect --format '{{.State.Pid}}, {{.Name}}' | grep "%PID%"

You can find all parents for this process:
pstree -sg <PID>
This chain will be contains the container

You should be able to use exec against each running container checking if the pid exists. Of course the same process id could exists in more than one container. Here is a small bash script that search for a running process based on the supplied pid in each container:
#!/bin/bash
for container in $(docker ps -q); do
status=`docker exec $container ls /proc/$1 2>/dev/null`
if [ ! -z "$status" ]; then
name=`docker ps --filter ID=$container --format "{{.Names}}"`
echo "PID: $1 found in $container ($name)"
break;
fi
done;
For example:
./find-process.sh 1

I kinda combined all of these and wrote this two liner. Hopefully useful to someone.
#!/bin/bash
SCAN_PID=`pstree -sg $1 | head -n 1 | grep -Po 'shim\([0-9]+\)---[a-z]+\(\K[^)]*'`
docker ps -q | xargs docker inspect --format '{{.State.Pid}}, {{.Name}}' | grep "${SCAN_PID}"
First line finds the container entry script and feeds it to the docker inspect.

You can cycle through the parent processes of the target process using ps -o ppid= and at each step check if the PID of the parent matches one of the containers.
#!/bin/bash
targetpid=$1
parentpid=0
while [ $parentpid != 1 ]; do
parentpid=$(ps -o ppid= $targetpid)
docker ps -q | xargs docker inspect --format '{{.State.Pid}}, {{.Name}}' | grep "^$parentpid"
targetpid="$parentpid"
done

Related

How can I restore all of my lost Docker containers?

After a restart of VM I was not able to run any docker command. I follow some question on stack overflow and run the following command ps axf | grep docker | grep -v grep | awk '{print "kill -9 " $1}' | sudo sh
Now There is no image or container.
Result of commands
docker ps and ps -a
docker images list
docker ls
docker ls -a
All the command return empty list. Everything has been clean up.
Is there any way to find our backups or restore the deleted containers?

How can stop group of containers with regex in docker-compose

Question:
How can I stop containers that their names start with server-?
Containers
> sudo docker-compose ps
Name Command State Ports
-----------------------------------------------------------------------------------------------------------------------------------------------
server-myservername1_1 some commands Up
server-myservername2_1 some commands Up
server-myservername3_1 some commands Up
server-myservername4_1 some commands Up
server-myservername5_1 some commands Up
server-myservername6_1 some commands Up
console-myconsolename1_1 some commands Up
console-myconsolename2_1 some commands Up
First check the output of below command if it's gives the names of only those containers that you have to stop
docker-compose ps | grep server | awk '{print $1}'
If the list is right, then run
docker stop $(docker-compose ps | grep server | awk '{print $1}')
P.S. I haven't tested the above command. Let me know if it doesn't
You can simply use --filter option of ps command
Suppose you wanna look for 3 containers, which their names start with site
docker ps --filter name=site*
will show you stat of those three containers.
so use one of this to stop the containers
- docker ps --filter name=site* -aq | xargs docker stop
- docker stop $(docker ps --filter name=site* -aq)

Stop docker containers with name matching a pattern

I'm using puckel/docker-airflow with CeleryExecutor. It launches a total of 5 containers named like this
docker-airflow_flower_1_de2035f778e6
docker-airflow_redis_1_49d2e710e82b
..
While development, I often have to stop all above containers. However, I can't do a docker stop $(docker ps -aq) since I have other containers running on my machine too.
Is there a way to stop all containers who's names match a given pattern (for instance all containers who's names start with docker-airflow in above)?
From this article by #james-coyle, following command works for me
docker ps --filter name=docker-airflow* --filter status=running -aq | xargs docker stop
I believe docker CLI natively does not provide such a functionality, so we have to rely on filtering and good-old bash PIPE and xargs
UPDATE-1
Note that depending on your environment, you might have to do these
run docker commands with sudo (just prefix both docker .. commands above with sudo)
enclose name pattern in double-quotes --filter name="docker-airflow*" (particularly on zsh)
Better late than never ;). From this article. The following works for me:
Stop containers with names matching a given pattern:
$ docker container stop $(docker container ls -q --filter name=<pattern>)
On the other hand, if we want to start containers with names matching a given pattern:
$ docker container start $(docker container ls --all -q --filter name=<pattern>)
NOTE: For different environments related tips, #y2k-shubham's update is a good starting point.
Another approach using grep and docker ps:
To stop docker container matching the given pattern/list of pattern":
docker ps | grep -E "name_1|name_2|name_3" | awk '{print $1}' | xargs docker stop
To stop docker container excluding the given pattern/list of pattern:
docker ps | grep -Ev "name_1|name_2|name_3" | awk '{print $1}' | xargs docker stop
Reference: Grep

how to identify if any applications inside docker container as running as root

We use a lot of 3rd party images [Eg: gitlab , jenkins, centos7 ..] which we run inside our docker containers. I would like to know how to check if any of the applications running in the container is run as root user. Is it the same as checking on a normal server ps -elf|grep root but inside the container.
Running Containers
To get all processes and their UIDs inside your running containers on a host, you can do the following:
for c in $(docker ps -q); do docker inspect $c -f "{{ .Name }}:"; docker top $c | awk '{print $1, $2, $8}'; echo "--------------"; done
This will print something like
/webserver-dockerized_nginx_1:
UID PID CMD
root 13437 nginx:
systemd+ 13522 nginx:
systemd+ 13526 nginx:
systemd+ 13527 nginx:
systemd+ 13528 nginx:
--------------
for all containers you have running.
Images
To get the configured users for all images on a host you can do
docker image inspect $(docker image ls -q) -f "{{ .RepoTags }}: {{ .ContainerConfig.User }} {{ .Config.User }}"
This will output something like
[nginx:mainline-alpine]:
[memcached:alpine]: memcache memcache
[redis:5-alpine]:
As Marvin mentioned: If there is no user in the output, no USER was defined in the Dockerfile, thus the container will run as root (Reference: Docker Documentation)
You can attach the terminal to your running container and once you're inside you can run the ps command:
Attaching to the container
$ docker exec -it <container_id> /bin/bash
You can read more about docker exec in the official docs site: https://docs.docker.com/engine/reference/commandline/exec/
Hope it helps!
You could use docker top command in association with the process id...
Combining "docker ps" and "docker top" could make the thing..
You could do stg like that :
docker ps | perl -ne '#cols = split /\s{2,}/, $_; printf "%15s\n", $cols[0]' > tmp.txt && tail -n $(($(wc -l < tmp.txt)-1)) tmp.txt | xargs -L1 docker top | perl -ne '#cols = split /\s{2,}/, $_; printf "%15s %65s\n", $cols[0], $cols[7]' && rm tmp.txt
That's not a perfect answer ((ould be prettyfied), and also note that it only works for running container. It'd be safer to check this from a image point of view, before you run the container.
Then, every time you get an image, just check this way :
d image inspect <image id> | grep -i user
I might be wrong, but I think no user means root. Otherwise, you will have to analyse the output there.

Shell command to Get container id from "docker ps"

I am basically looking to achieve this 2 steps:
1. Run the docker image:
docker run -p 80:80 some-image-name:25
2. Now "docker ps" returns whole data about the container but I was looking for just the container ID to
3. run some test on it.. ex.
docker exec -it /usr/bin/npm run test
So my question is how I can get just the container id from step 2.
Note: I need this flow for my pipeline script in Jenkins.
docker ps -a -q
This will give you only container's id
You could use awk to get the container ID's as follows:
docker ps | awk 'NR > 1 {print $1}'
This one-liner outputs all the container ID's printed by docker ps. To get only the first one you would use:
docker ps | awk 'NR > 1 {print $1; exit}'
Even though that answers your question I recommend that you use container names instead of relying on container ID's.
P.S.: This solution is on average 1 millisecond slower than docker ps -q, but it is significantly more flexible.
docker ps --format {{.ID}}
Will return only the ids of running containers.
you can use docker functionality to get this done:
docker ps --filter volume=remote-volume --format "table {{.ID}}\t{{.Mounts}}"
with --format "{{.ID}}" you'd get the ids only. You can also filter. Read the documentation of docker ps for more details
All the below command give you container id's
docker ps -aqf "name=containername"
docker ps --no-trunc -aqf name=containername
docker container ls | grep 'container-name' | awk '{print $1}'```
You can get container ID using following command:
docker ps -q

Resources