By Alwyn Botha, Alibaba Cloud Tech Share Author. Tech Share is Alibaba Cloud's incentive program to encourage the sharing of technical knowledge and best practices within the cloud community.
This tutorial provides a quick demonstration of the 25 Docker commands that can be applied against containers. The article is structured so that you get to use the following 25 commands at least once each. This will help provide a better understanding of containers from a high-level perspective, such as what containers are and what you can do with them.
From https://docs.docker.com/engine/reference/commandline/container_inspect/#description
docker container inspect : Display detailed information on one or more containers
Fortunately we can inspect stopped containers as well, so we can just run:
docker container inspect mycontain
You will see a long list of all the settings applied to this container.
Right at the top you will also see its current status : exited.
"State": {
"Status": "exited",
"Running": false,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
Note that dead = false. That would indicate a somehow seriously broken container. Exited containers can be restarted ( as we did above ) but if you someday get a dead container I doubt that can be restarted.
These 2 commands have different uses:
This part of the tutorial will use several docker container commands discussed in part 1 and this part 2.
You can use the same overall approach to make tiny changes - then observe results - to your containers while you are busy developing.
The plan
Phase 1: signals
Phase 2: environment variables
nano traps
Please remove that remove-me text. Markdown must have headings start with hash, so script first lines are rendered as headings. Insane absurd but true.
remove-me#!/bin/bash
function SIGINT_trap() {
echo . . . SIGINT signal caught
echo . . . doing SIGINT cleanup
exit
}
function SIGTERM_trap() {
echo . . . SIGTERM signal caught
echo . . . doing SIGTERM cleanup
exit
}
trap SIGINT_trap SIGINT
trap SIGTERM_trap SIGTERM
for i in `seq 1 50`; do
sleep 1
echo -n " . "
echo $i
done
exit 0
Line 14 and 15 will call the relevant function based on the signal received.
nano Dockerfile
Dockerfile content:
FROM alpine:3.8
ENV myvar original value
COPY traps /root/
RUN chmod +x /root/traps
CMD ["/bin/sh", "/root/traps"]
Build that image:
docker build --tag mytraps:demo --file Dockerfile .
Start a second shell. Run:
docker container logs mycontain -f
You will get error, that is OK - we have not started container yet.
This step is to get that command in the shell history so we can quickly get at it. You will see below.
First shell:
docker container run -d --name mycontain mytraps:demo
Second shell:
Press up arrow key to get previous command and press ENTER. You will see the bash script output.
Run in first shell:
docker container kill --signal 15 mycontain
Second shell:
Expected output :
...
. 15
. 16
. 17
. 18
. 19
. . . SIGTERM signal caught
. . . doing SIGTERM cleanup
SIGTERM / 15 signal got caught - script is doing SIGTERM cleanup.
Note that log output now stops as well: the container exited successfully after processing the signal processing function.
Test 1 complete: signal TERM / 15 processed success.
Remove previous exited container:
Run in first shell:
docker container prune -f
Start container again:
docker container run -d --name mycontain mytraps:demo
Second shell:
Press up arrow key to get previous command and press ENTER. You will see the bash script output just like before.
Run in first shell:
docker container kill --signal SIGINT mycontain
Second shell:
Expected output :
...
. 16
. 17
. 18
. 19
. 20
. . . SIGINT signal caught
. . . doing SIGINT cleanup
SIGINT signal got caught - script is doing SIGINT cleanup.
Note that log output now stops as well: the container exited successfully after processing the signal processing function.
Test 2 complete: signal SIGINT / 2 processed success.
Test 3: KILL signal
Remove previous exited container:
Run in first shell:
docker container prune -f
Start container again:
docker container run -d --name mycontain mytraps:demo
Second shell:
Press up arrow key to get previous command and press ENTER. You will see the bash script output just like before.
Run in first shell:
docker container kill --signal SIGKILL mycontain
Second shell:
Expected output :
...
. 6
. 7
. 8
. 9
. 10
. 11
. 12
SIGKILL signal cannot be caught - script cannot do any cleanup routines.
Note that log output now stops as well: the container exited UNsuccessfully after being rudely KILLed immediately via KILL signal.
Test 3 complete: signal SIGKILL / 2 processed success.
Important summary: your processes running in your containers must have the proper cleanup routines. With Docker you will be shutting down and restart containers much more frequently than in the pre-Docker world. So its critical your containers can correctly handle all the different ways of being shut down.
Based on these exercises you see how easy it is to test handling just 2 signals.
If you enter trap -l at your shell you will see a list of 64 possible signals. Your processes must be able to handle all the possible values they can receive.
docker container kill is wrongly named.
It should have been: docker container signal - since you can send signals just to re-read configuration files. Not all signals kill.
You can use SIGUSR1 and SIGUSR2 for any purpose - send your applications those signals and let it mean anything - not just KILL.
From https://docs.docker.com/engine/reference/commandline/container_wait/
Block until one or more containers stop, then print their exit codes
To investigate how this works, we are going to run 3 containers, let them sleep a few seconds and then exit with unique exit codes.
Cut and paste the following to your shell:
docker container run -d --name mycontain1 mytraps:demo sh -c 'sleep 10;exit 1'
docker container run -d --name mycontain2 mytraps:demo sh -c 'sleep 15;exit 2'
docker container run -d --name mycontain3 mytraps:demo sh -c 'sleep 25;exit 3'
Start a new shell console session and run:
docker container wait mycontain1 mycontain2 mycontain3
Note that as the containers sleep period runs down, they exit with the specified exit code.
There is no indication of which container exited with which exit code, which is frankly quite lame.
If you need to know which container exited with which exit code use:
docker ps -a
Expected output :
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6c7fe618e23b mytraps:demo "sh -c 'sleep 25;exi…" 40 seconds ago Exited (3) 14 seconds ago mycontain3
d4e1bb11e55c mytraps:demo "sh -c 'sleep 15;exi…" 43 seconds ago Exited (2) 27 seconds ago mycontain2
bee5cbf37052 mytraps:demo "sh -c 'sleep 10;exi…" 44 seconds ago Exited (1) 33 seconds ago mycontain1
This functionality is not very exiting but may have some use case: you have several batch containers that may run for maybe an hour or more. You expect all to complete successfully.
Instead of running docker ps -a every few minutes ( breaking your otherwise thinking workflows ), you can use this command in a new shell to watch those containers for you. When all your many containers finishes the command will show the prompt again: if you have a list of zeros shown then success ... all containers exited successfully.
(No output shown for commands below. Try them by yourself. )
You can use :
docker ps -a --filter "name=mycontain1" --filter "name=mycontain2" --filter "name=mycontain3"
but this is really longwinded.
Note all containers use the same image: mytraps:demo
docker ps -a --filter "ancestor=mytraps:demo"
ancestor filter: Filters containers which share a given image as an ancestor.
Much shorter than before.
The shortest typing winner is
docker ps -a | grep mycontain
or even ( in this case )
docker ps -a | grep mytraps
If you define an alias mypsa:
alias mypsa='docker ps -a | grep '
then you can use :
mypsa traps
mypsa contain
List port mappings or a specific mapping for the container
docker ps -a also shows port mappings. Therefore I am not going to investigate this command here.
Prune stopped containers:
docker container prune -f
docker image rm mytraps:demo
We used alpine:3.8 image a lot. Since you will probably use it in future I suggest you do not delete it.
In these 2 tutorials you used nearly all 25 docker container commands. You now have a good understanding of what commands you can apply against your containers.
If you want to become a Docker expert in shortest time I suggest you do similar tiny and quick ( but very useful ) exercises with all the Docker functionalities.
2,599 posts | 762 followers
FollowAlibaba Clouder - March 11, 2019
Alibaba Clouder - June 11, 2020
Alibaba Clouder - December 28, 2018
Alibaba Clouder - January 24, 2019
Alibaba Clouder - September 16, 2019
Alibaba Cloud Community - December 31, 2021
2,599 posts | 762 followers
FollowLearn More
Alibaba Cloud Container Service for Kubernetes is a fully managed cloud container management service that supports native Kubernetes and integrates with other Alibaba Cloud products.
Learn MoreElastic and secure virtual cloud servers to cater all your cloud hosting needs.
Learn MoreMore Posts by Alibaba Clouder