Docker restarting specific service of multiple docker-compose process tags - bash

I have multiple sets two of Docker services running simultaneously, so my docker ps logs look something like this:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0a8e26682915 image_name:latest "bash -c 'pip instal…" About a minute ago Up About a minute process_name_1_actions_1
ed8b56ff29b1 image_name:latest "bash -c 'cd live-bo…" About a minute ago Up About a minute 0.0.0.0:5005->5005/tcp, :::5005->5005/tcp process_name_1_model_1
6d8016412d12 image_name:latest "bash -c 'pip instal…" About a minute ago Up About a minute process_name_2_actions_1
128d3605297a image_name:latest "bash -c 'cd live-bo…" About a minute ago Up About a minute 0.0.0.0:5006->5005/tcp, :::5006->5005/tcp process_name_2_model_1
Note that the names of these services have tags. I would like to create a shell script which can loop through these sets of processes by their tags, and restart the actions_1 service. Something like:
declare -a arr=("process_1" "process_2")
for i in "${arr[#]}"
do
# here, restart only the 'actions_1' service of process i.
done
Justification for this is that the processes titled _model_1 takes a long time to spawn. The process titled _actions_1 needs to be restarted often, and does not take a long time to spawn. For this reason, running docker-compose down followed by docker-compose up is a very tedious process.

Use this command
docker ps --format '{{.Names}} {{.ID}}' | awk '{if ($1 ~ "_actions_1") print $2;}' | xargs -P 10 docker restart
Description ::
docker ps --format '{{.Names}} {{.ID}}: Lists current containers running with only 2 fields - name & id
awk: Checks $1 i.e. image name via regex, if matches, then prints corresponding $2 i.e. container id
xargs Executes specified command one by one upon the output. -P 10 executes 10 restarts in parallel at most, to speed things up.

Related

How to obtain container id base on docker image name via command line ?

If I ran sudo doccker ps I got this
[user#vm1 ~]$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e8ff73dec1d5 portal-mhn:latest "nginx -g 'daemon of…" 43 minutes ago Up 43 minutes portal-mhn_portal-mhn.1.4rsfv94wy97gb333q3kfyxz32
62a7cf09d7bf portal-admin:latest "nginx -g 'daemon of…" 43 minutes ago Up 43 minutes portal-admin_portal-admin.1.s62iep4gl5g5oj2hrap14kz1t
I'm trying to grab the container ID base on ImageName.
Ex. Is there away to grab the container id of portal-mhn:latest via a command line ? which is e8ff73dec1d5
If you want to get the container id based on the image name this should work:
$ docker ps | grep '<image_name>' | awk '{ print $1 }'
Or even:
$ docker ps | awk '/<image_name>/ { print $1 }'
As others have suggested you can also directly filter by the image name using the ancestor filter:
$ docker ps -aqf "ancestor=<image_name>"
Thanks to #kevin-cui and #yu-chen.
The accepted answer works, but you might possibly have a misnamed container name that has postgres in its name but is actually running a totally different image, since the answer only uses grep to look for matching lines.
You can use Docker's built in filter flag:
docker ps --filter "ancestor=postgres" -q
as an alternative. The -q flag indicates to only return the container ID (quiet mode).
I needed only to obtain the latest running container id by image name, including stopped containers:
docker ps -a | grep 'django-content-services:' -m 1 | awk '{ print $1 }'
In docker -a to include all containers (even stopped). In grep, -m so grep only matches the first case. Cheers!

Unable to Find Entrypoint For Nextcloud (Alpine-based Version) For a Cron Container

I'm using Docker with Rancher v1.6, setting up a Nextcloud stack.
I would like to use a dedicated container for running cron tasks every 15 minutes.
The "normal" Nextcloud Docker image can simply use the following:
entrypoint: |
bash -c 'bash -s <<EOF
trap "break;exit" SIGHUP SIGINT SIGTERM
while /bin/true; do
su -s "/bin/bash" -c "/usr/local/bin/php /var/www/html/cron.php" www-data
echo $$(date) - Running cron finished
sleep 900
done
EOF'
(Pulled from this GitHub post)
However, the Alpine-based image does not have bash, and so it cannot be used.
I found this script in the list of examples:
#!/bin/sh
set -eu
exec busybox crond -f -l 0 -L /dev/stdout
However, I cannot seem to get that working with my docker-compose.yml file.
I don't want to use an external file, just to have the script entirely in the docker-compose.yml file, to make preparation and changes a bit easier.
Thank you!

Remote login (ssh differences)

I would like to know what is the difference between the below commands:
ssh vagrant#someipaddress
cd /home/vagrant/
grep -i "something" data.txt
and
ssh vagrant#someipaddress 'cd /home/vagrant; cat data.txt' | grep -i "something"
From this website it mentions, that you can send multiple commands to the remote server. Is the second option actually logging into the server? What is the benefit in this second approach?
Strictly Speaking from the example provided:
The first command:
Logs onto the remote server
Executes a couple commands, and
Stays logged on to the server
The second command runs half on the remote machine, logs out of the remote machine, and then pipes the output to grep on your local machine, all in one command line.
Breaking down what's happening:
ssh vagrant#someipaddress 'cd /home/vagrant; cat data.txt' | grep -i "something"
The section in bold is running on your local PC, based on the output from the ssh session
The 'quotes "contain" the entire command block
the " quotes "contain" the individual arguments within the command block.
You may have meant to do this:
ssh vagrant#someipaddress 'cd /home/vagrant; cat data.txt' | grep -i "something"
Where the bold section runs locally
Or you may have intentionally done this:
ssh vagrant#someipaddress 'cd /home/vagrant/ | grep -i "something" data.txt'
Where the entire command runs on the server.
Either way, the end result:
Is that you automatically log out of the remote machine, and the whole command sequence was executed in one hit.

Why does docker run -t keep the bash process from exiting and stopping the container

I understand that a docker container will stop once the main process (the command) ends.
I also understand that the -t will allocate a pseudo TTY
docker run -t <image> <command>
Now, when I run bash by default the container stops immediately, which is expected
docker run fedora bash
docker -ps =>(this gives empty list)
But when I run bash with -t like this
docker run -t fedora bash
[CTRL+C]
docker ps =>(this shows one running container)
Why does -t keep the bash process running? Although the same -t will not keep, for example, echo running
docker run -t fedora echo "hello"
[CTRL+C]
docker ps =>(this shows empty list although we added -t)
When you use bash without -t it exits with status 0 immediately since you're not supplying any command to bash using -c option.
By using -t you are allocating a pseudo-tty to bash process. However you're not using another important -i option that keeps STDIN open even if not attached. Without -i you cannot type anything inside the bash hence bash keeps running waiting for the next command.
echo command exits with status 0 immediately because echo is not an interactive process like bash.
So right way to start bash is:
docker run -it fedora bash
As per official documentation:
For interactive processes (like a shell), you must use -i -t together in order to allocate a tty for the container process. -i -t is often written -it.

Bash script to get into a running container and then run another bash script from that container

I have a shell script which runs as follows :
image_id=$(docker ps -a | grep postgres | awk -F' ' '{print $1}')
full_id=$(docker ps -a --no-trunc -q | grep $image_id)
docker exec -i -t $full_id bash
When I run this from the base linux OS, I expect to actually enter the postgres container which is a running container. But the issue is that the shell script hangs on 3rd line during ' docker exec' step.
My end goal is using the bash script, enter a running postgres container and run another bash script inside that container.
However the same command when I run it from command line, it works fine and gets me into the postgres container.
Please help, I have spent hours and hours to solve this but no progress.
Thanks again
Your setup is a bit more complex than it needs to be.
Docker ps can filter containers directly with the --filter= option
docker ps --no-trunc --quiet --filter="ancestor=postgres"
You can also --name containers when you run them which will be less fraught with danger than the script you are attempting
docker run --detach --name postgres_whatever postgres
docker exec -ti postgres_whatever bash
I'm not sure that your script is hanging as opposed to sitting there waiting for input. Try running a command directly
Using naming
exec_test.sh
#!/usr/bin/env bash
docker exec postgres_whatever echo "I have run the test"
When run
$ ./exec_test.sh
I have run the test
Without naming
exec_filter_test.sh
#!/usr/bin/env bash
id=$(docker ps --no-trunc --quiet --filter="ancestor=postgres")
[ -z "$id" ] && echo "no id" && exit 1
docker exec "${id}" echo "I have run the test"
When run
$ ./exec_filter_test.sh
I have run the test

Resources