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 gives you practical experience in cleaning up Docker containers.
You need only about a week's experience with Docker to be able to understand most of this tutorial.
You need more experience as Linux administrator, since grep, awk and xargs is also used.
grep, awk and xargs are very powerful tools to use at the shell command line. It is worthwhile spending a day reading and executing tutorials on these tools. This tutorial focus on Docker; it will only give ten line descriptions where grep, awk and xargs are used. ( It only explains the one percent of grep, awk and xargs functionality we need to understand in the context of using it in docker cleanups. )
To follow this tutorial you need an Alibaba Cloud Elastic Compute Service (ECS) server with Docker already installed. If you are not sure how, you can refer to this tutorial.
In order to learn about cleaning up containers we need some containers to clean up.
First we need some images from https://hub.docker.com/
For the purposes of this tutorial it does not matter at all what is inside those images. You need zero experience of Nginx, Redis and Alpine to understand this full tutorial completely.
Redis is an open source, in-memory data structure store, used as a database and data cache. Most programming languages can use it to make the programs faster via near-instant access to data in memory.
NGINX is a free, open-source, high-performance HTTP server: competing directly with more well-known Apache web server.
Alpine Linux is a 5MB Linux distribution, very popular with docker users.
Alpine Linux is used as a base image for docker applications. It provides a small Linux environment for running apps.
Enter the following at your shell prompt to get these 4 images downloaded onto your computer.
docker pull hello-world:latest
docker pull nginx:mainline-alpine
docker pull redis:alpine
docker pull alpine:3.8
The docker pull command downloads Docker images from a registry. A docker registry contains a collection of Docker images.
By default, the docker pull command pulls / downloads docker images from Docker Hub: https://hub.docker.com/
Docker images are used to create running containers. Docker images contain all the software needed to run a specific application. For example, the nginx:mainline-alpine image you downloaded contains all the software needed to run Nginx in a container.
In docker pull nginx:mainline-alpine the nginx:mainline-alpine is the name of the image we want to pull / download. The image name is nginx.
The mainline-alpine is a tag. Tags are used to differentiate different versions of the same image, for example: there could be nginx:centos, nginx:ubuntu, nginx:debian8 and nginx: debian9 images at the Docker Hub repository. We use tags to specify exactly which image to download.
In the case of docker pull alpine:3.8 the 3.8 tag represents a version number.
Run:
docker ps -a
Expected output:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
If you are running this on a fresh docker install server you will have no running containers.
Let's make a mess and create several containers to clean up. Enter these commands:
docker run --name nginx -d nginx:mainline-alpine
docker run --name redis -d redis:alpine
docker run -d hello-world
docker run -d hello-world
docker run -d hello-world
The docker run will turn the static images you downloaded before into executing containers.
A container is a runtime version of a docker image. The container contains all the software from the Docker image as well as a complete execution environment including running processes.
We do not need nginx or redis functionality in this tutorial. We only need an interesting list of varied containers. Then we can better learn how to selectively stop and delete containers.
Let's stop nginx and redis. The hello-world container only displays a message and then exits. There is no need to stop it, its already stopped.
docker stop nginx
docker stop redis
List all containers by entering this command:
docker ps -a
Expected output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
97f95b11260e hello-world "/hello" 57 seconds ago Exited (0) 44 seconds ago determined_payne
91f69bd08bf8 hello-world "/hello" About a minute ago Exited (0) About a minute ago xenodochial_wiles
6f7b53de6ad7 hello-world "/hello" About a minute ago Exited (0) About a minute ago pedantic_bartik
62919b9e6d84 redis:alpine "docker-entrypoint.s? About a minute ago Exited (0) 3 seconds ago redis
49ca281f8a0c nginx:mainline-alpine "nginx -g 'daemon of? 2 minutes ago Exited (0) 14 seconds ago nginx
The CONTAINER IDs you get when you run these commands on your computer will be different.
We now have 5 stopped containers
We cannot use
docker container prune
That command will prune/remove ALL stopped containers. Let's assume we still want to look at nginx and redis logs. Therefore we must carefully prune just the hello-world containers.
Let's build a list of JUST the hello world containers. Run
docker ps -a | grep "hello-world"
grep will select only the output lines that contain the text: hello-world
grep is a Linux shell utility ava on most Linux distributions. It was written 40 years ago.
grep is used to search plain-text input for lines that match its search expression.
The __ docker ps -a __ lists all containers, the pipe symbol | sends this list to grep. __ grep "hello-world" __ searches for the text __ hello-word __. grep only outputs the list of containers __ containing hello-word. __
Grep stands for: g/re/p (__g__lobally search a __re__gular expression and __p__rint)
In __ docker ps -a | grep "hello-world" __ grep searched the list of containers output by docker ps, and prints only the lines containing hello-world.
grep searches the input files for lines containing a match to a given pattern list. When it finds a match in a line, it copies the line to standard output (by default), or whatever other sort of output you have requested with options.
Expected output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
97f95b11260e hello-world "/hello" About a minute ago Exited (0) About a minute ago determined_payne
91f69bd08bf8 hello-world "/hello" 2 minutes ago Exited (0) About a minute ago xenodochial_wiles
6f7b53de6ad7 hello-world "/hello" 2 minutes ago Exited (0) 2 minutes ago pedantic_bartik
Perfect. We need a list of just the containers we want to prune.
Alternatively we could run:
docker ps -a | egrep --invert-match "redis|nginx"
The --invert-match inverts the matching, it only selects non-matching lines. -v is shortcut form for --invert-match
"redis|nginx" is a regular expression that selects only text containing redis or nginx. Here the pipe symbol | means or.
Here egrep will select only the output lines that EXCLUDES the text redis and EXCLUDES the text nginx
We use egrep here: this grep supports extended regular expressions: "redis|nginx" is the extended regular expression used in this case.
docker container __ rm __ = docker container __ remove __ / delete / prune
The format of docker container rm is:
docker container rm [OPTIONS] CONTAINER [CONTAINER...]
We need just a list of container IDs to pass to docker container rm
Container IDs are field number one of the output. awk '{print $1}' prints just the first field passed to it.
AWK is a programming language designed for text processing . It is used to extract and filter text data. It is a installed on most Linux distributions.
AWK was created in 1970. The AWK name is derived from the surnames of its authors Alfred Aho, Peter Weinberger, and Brian Kernighan.
awk and grep both filters text. They each have unique features. grep cannot print input columns selectively. It is a feature only awk has. So we have to use grep and awk.
awk '{print $1}' prints just the first field passed to it. awk by default assumes fields are separated by white space characters. Using __ awk '{print $1}' __ in our case will print the containers IDs, the first field / column in docker ps -a output.
Run:
docker ps -a | grep "hello-world" | awk '{print $1}'
Expected output
97f95b11260e
91f69bd08bf8
6f7b53de6ad7
Let's remove all 3 those hello-world containers. Pick one of the following commands to run:
docker ps -a | grep "hello-world" | awk '{print $1}' | __ xargs docker container rm __
or
docker ps -a | egrep -v "redis|nginx" | awk '{print $1}' | __ xargs docker container rm __
xargs docker container rm receives the container IDs one by one and removes them.
Expected output
97f95b11260e
91f69bd08bf8
6f7b53de6ad7
Perfect. docker container rm shows the container IDs that it removed.
Run:
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
62919b9e6d84 redis:alpine "docker-entrypoint.s? 4 minutes ago Exited (0) 2 minutes ago redis
49ca281f8a0c nginx:mainline-alpine "nginx -g 'daemon of? 4 minutes ago Exited (0) 2 minutes ago nginx
redis and nginx still exists.
Let's investigate those redis and nginx logs so that we can remove those containers as well. docker logs shows the logs of a container.
docker logs redis
1:C 03 Oct 06:40:25.554 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:C 03 Oct 06:40:25.559 # Redis version=4.0.11, bits=64, commit=00000000, modified=0, pid=1, just started
1:C 03 Oct 06:40:25.559 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
1:M 03 Oct 06:40:25.613 * Running mode=standalone, port=6379.
1:M 03 Oct 06:40:25.614 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
1:M 03 Oct 06:40:25.614 # Server initialized
1:M 03 Oct 06:40:25.614 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
1:M 03 Oct 06:40:25.615 * Ready to accept connections
1:signal-handler (1538548914) Received SIGTERM scheduling shutdown...
1:M 03 Oct 06:41:54.159 # User requested shutdown...
1:M 03 Oct 06:41:54.195 * Saving the final RDB snapshot before exiting.
1:M 03 Oct 06:41:54.233 * DB saved on disk
1:M 03 Oct 06:41:54.233 # Redis is now ready to exit, bye bye...
Run:
docker logs nginx
There is nothing shown. We did not even use nginx container for anything.
Mini investigation of logs complete. Now we can remove all containers.
Run:
docker container prune -f
Deleted Containers:
62919b9e6d844d6720301dd8be7d0dfb58defb593fe8e9fa1ea0984b7aa92baa
49ca281f8a0cdc3adaddd222a654c4e61b17861f3a20dd9b584d0073466c722d
Total reclaimed space: 0B
2 container IDs shown. Those containers are now deleted as well.
Run:
docker ps -a
Expected output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
As expected, no containers running or stopped.
Summary
First we learnt to remove containers by grepping only the text we want then selecting just the container IDs via awk.
Second we pass the container IDs to xargs docker container rm which removes the passed containers.
docker ps -a | grep "hello-world" | awk '{print $1}' | xargs docker container rm
alternatively:
docker ps -a | egrep -v "redis|nginx" | awk '{print $1}' | xargs docker container rm
docker run -d hello-world
Run it twice more so that we have 3 containers to cleanup.
docker run hello-world ; docker run hello-world
Run:
docker container ls
It shows nothing since it only shows running containers.
Run:
docker container ls -a
The -a show all containers; including stopped ones.
Expected output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
60cc61444c0b hello-world "/hello" 45 seconds ago Exited (0) 37 seconds ago pensive_albattani
e820b8032706 hello-world "/hello" About a minute ago Exited (0) 51 seconds ago silly_lovelace
7e959fd100d0 hello-world "/hello" About a minute ago Exited (0) About a minute ago fervent_kilby
The command docker container prune removes all stopped containers
The command docker container prune --force removes all stopped containers but do not prompt for confirmation
Let's run
docker container prune -f
Expected output
Deleted Containers:
60cc61444c0b90c7f2b0ada1546c3913a93676bbb0ba0dfb1c9329268222df6d
e820b803270681be048b511d676af56e28778e92ef783a536a4272f7d9648bd6
7e959fd100d0a72311f25987a0d0b6d1960283f2b164e56c538baddad83e8446
Total reclaimed space: 0B
3 containers deleted. On prune option the -f is shortcut for --force.
Labels are used in docker to group related containers. Containers can then be selectively processed by selecting it based on label values.
The command docker container prune supports deleting containers using labels as filters.
The currently supported filters are:
until () - only remove containers created before given timestamp
label - only remove containers with (or without, in case label!=... is used) the specified labels.
Let's create 3 containers using labels this time.
Execute these 3 commands:
docker run -d --label hello-1 hello-world
docker run -d --label hello-2 hello-world
docker run -d --label hello-3 hello-world
The docker ps -a command does not show labels. To show labels we need to use the --format option.
Complete --format reference at
https://docs.docker.com/engine/reference/commandline/ps/#formatting
Run:
docker ps -a --format 'table {{.Image}}\t{{.Labels}}\t{{.Command}}\t{{.Status}}'
Expected output
IMAGE LABELS COMMAND STATUS
hello-world hello-3= "/hello" Exited (0) 1 minutes ago
hello-world hello-2= "/hello" Exited (0) 1 minutes ago
hello-world hello-1= "/hello" Exited (0) 1 minutes ago
Let's selectively prune just the hello-1 container by running:
docker container prune --force --filter "label=hello-1"
Expected output
Deleted Containers:
1aa4c41c7a5b164edb4bb08cec4ec8c9769fb3e7dc311c825321fc7f87989ea9
Total reclaimed space: 0B
Rerun the command:
docker ps -a --format 'table {{.Image}}\t{{.Labels}}\t{{.Command}}\t{{.Status}}'
IMAGE LABELS COMMAND STATUS
hello-world hello-3= "/hello" Exited (0) 4 minutes ago
hello-world hello-2= "/hello" Exited (0) 4 minutes ago
Now only 2 containers remain.
Let's prune these 2 containers by running:
docker container prune -f
then run
docker ps -a
Expected output
IMAGE LABELS COMMAND STATUS
All containers pruned. Labels are a good way to selectively prune one container with a specific label.
It just as useful to prune several containers if they all share the same label.
From https://docs.docker.com/engine/reference/commandline/ps/#filtering
name::: Container name
label::: An arbitrary string representing either a key or a key-value pair. Expressed as or =
ancestor::: Filters containers which share a given image as an ancestor. Expressed as [:], , or
volume::: Filters running containers which have mounted a given volume or bind mount.
network::: Filters running containers connected to a given network.
publish or expose::: Filters containers which publish or expose a given port. Expressed as port[/protocol]
Since these 3 containers share the same ancestor image: __ hello-word:latest__, they could easily have been pruned with this one command:
docker container prune --force --filter __ "ancestor=hello-word:latest" __
If these 3 containers used the same network for example: __ mytestnetwork__, they could easily have been pruned with this one command:
docker container prune --force --filter __ "network=mytestnetwork" __
Exit status represent the success status of the processes in an exited container.
Exit status of zero normally means success ( across operating systems and programming languages: exit status 0 = success ).
The specific numeric value of the exit status has predefined value for specific programming languages and programs: for example: 404 means webpage not found in Nginx and Apache web server.
The 123 and 9 exit status below are just random numbers, used to demonstrate how to clean up containers with different exit statuses.
Run the following commands to create 5 containers having 4 different exit status codes:
docker run -d alpine:3.8 /bin/sh -c 'exit 123'
docker run -d alpine:3.8 /bin/sh -c 'exit 9'
docker run -d alpine:3.8
docker run --name nginx -d nginx:mainline-alpine
docker run --name redis -d redis:alpine
Run the following to show the list of containers and their status exit codes:
docker ps -a
Expected output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9d4163879e17 redis:alpine "docker-entrypoint.s? 13 seconds ago Up 3 seconds 6379/tcp redis
2754c6805252 nginx:mainline-alpine "nginx -g 'daemon of? 26 seconds ago Up 15 seconds 80/tcp nginx
ef02229f40da alpine:3.8 "/bin/sh" 42 seconds ago Exited (0) 30 seconds ago epic_nobel
857cf388b70c alpine:3.8 "/bin/sh -c 'exit 9'" 59 seconds ago Exited (9) 46 seconds ago peaceful_torvalds
8b084d95a2fb alpine:3.8 "/bin/sh -c 'exit 12? About a minute ago Exited (123) About a minute ago pedantic_mirzakhani
nginx and redis are running, they have no exit codes yet.
Now run:
docker ps -a --filter status=exited
Expected output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ef02229f40da alpine:3.8 "/bin/sh" About a minute ago Exited (0) About a minute ago epic_nobel
857cf388b70c alpine:3.8 "/bin/sh -c 'exit 9'" About a minute ago Exited (9) About a minute ago peaceful_torvalds
8b084d95a2fb alpine:3.8 "/bin/sh -c 'exit 12? 2 minutes ago Exited (123) About a minute ago pedantic_mirzakhani
Only 3 exited containers shown since we specified --filter status=exited
docker ps -a --filter 'exited=0'
Expected output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ef02229f40da alpine:3.8 "/bin/sh" About a minute ago Exited (0) About a minute ago epic_nobel
Only 1 exited containers shown: the one with exited status = 0
Run
docker ps -a --filter 'exited=123'
Expected output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8b084d95a2fb alpine:3.8 "/bin/sh -c 'exit 12? 2 minutes ago Exited (123) 2 minutes ago pedantic_mirzakhani
Only 1 exited containers shown: the one with exited status = 123
Let's remove container with exit status = 0. Run:
docker ps -a --filter 'exited=0' | awk '{print $1}' | xargs docker container rm
Expected output
ef02229f40da
Error: No such container: CONTAINER
Run:
docker ps -a
Expected output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9d4163879e17 redis:alpine "docker-entrypoint.s? 4 minutes ago Up 3 minutes 6379/tcp redis
2754c6805252 nginx:mainline-alpine "nginx -g 'daemon of? 4 minutes ago Up 4 minutes 80/tcp nginx
857cf388b70c alpine:3.8 "/bin/sh -c 'exit 9'" 4 minutes ago Exited (9) 4 minutes ago peaceful_torvalds
8b084d95a2fb alpine:3.8 "/bin/sh -c 'exit 12? 5 minutes ago Exited (123) 4 minutes ago pedantic_mirzakhani
exited=0 container removed success.
Why the error:
Error: No such container: CONTAINER
Run:
docker ps -a --filter 'exited=9' | awk '{print $1}'
Expected output
CONTAINER
857cf388b70c
That CONTAINER header is the problem. We should only pass a list of container IDs to xargs docker container rm.
To fix the problem remove that CONTAINER header line using grep: grep -v CONTAINER
-v is shortcut form for --invert-match.
Run:
docker ps -a --filter 'exited=9' | awk '{print $1}' | grep -v CONTAINER
Expected output
857cf388b70c
Success: no CONTAINER header line shown.
These 2 lines have identical results:
docker ps -a --filter 'exited=9' | awk '{print $1}' | grep -v CONTAINER
Here docker ps filters exited 9 status code containers, awk prints first field, grep selects lines EXCLUDING the words CONTAINER.
alternative:
docker ps -a --filter 'exited=9' | grep -v CONTAINER | awk '{print $1}'
Here docker ps filters exited 9 status code containers, grep selects lines EXCLUDING the words CONTAINER, awk prints first field.
In general I would do selecting via grep first and then as a final step use awk to print only the required columns. Logically the steps flow better: grep selecting, then final awk print results.
Let's now remove the container with exited status 9 without getting the error message
Run:
docker ps -a --filter 'exited=9' | awk '{print $1}' | grep -v CONTAINER | xargs docker container rm
Expected output
857cf388b70c
Success: container removed and no error shown.
Let's now remove the container with exited status 123 without getting the error message
Run:
docker ps -a --filter 'exited=123' | awk '{print $1}' | grep -v CONTAINER | xargs docker container rm
Expected output
8b084d95a2fb
Success: container removed and no error shown.
Run:
docker ps -a
Expected output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9d4163879e17 redis:alpine "docker-entrypoint.s? 10 minutes ago Up 10 minutes 6379/tcp redis
2754c6805252 nginx:mainline-alpine "nginx -g 'daemon of? 10 minutes ago Up 10 minutes 80/tcp nginx
Only nginx and redis still running.
Sometimes you end up with a container in a created status. That happens when the container cannot get in the running status because of some error.
Let's create a container in a created status by deliberately cause an error during its startup run phase.
Run
docker run -d alpine:3.8 <span class=error> zxgarbagez </span>
Expected output
cc00b62dcb5078fed6d9e3fc48a9e5e7a9f3ef11d6722073781c3f5054696889
docker: Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "exec: \" <span class=error> zxgarbagez </span>\": executable file not found in $PATH": unknown.
Run:
docker ps -a
Expected output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cc00b62dcb50 alpine:3.8 "zxgarbagez" 28 seconds ago Created zealous_colden
9d4163879e17 redis:alpine "docker-entrypoint.s? 17 minutes ago Up 17 minutes 6379/tcp redis
2754c6805252 nginx:mainline-alpine "nginx -g 'daemon of? 17 minutes ago Up 17 minutes 80/tcp nginx
The zxgarbagez error causes the created status.
Let's list just such created containers.
docker ps --filter status=created
Expected output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cc00b62dcb50 alpine:3.8 "zxgarbagez" 28 seconds ago Created zealous_colden
Let's remove all containers in status=created
Run
docker ps --filter status=created | awk '{print $1}' | grep -v CONTAINER | xargs docker container rm
Expected output
cc00b62dcb50
Name of container shown as it gets removed.
Run:
docker ps -a
Expected output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9d4163879e17 redis:alpine "docker-entrypoint.s? 17 minutes ago Up 17 minutes 6379/tcp redis
2754c6805252 nginx:mainline-alpine "nginx -g 'daemon of? 17 minutes ago Up 17 minutes 80/tcp nginx
Only nginx and redis still running.
In this section we are going to pause a container and then attempt to remove it.
Docker uses the cgroups freezer functionality to freeze / pause all processes in a container.
With the cgroups freezer functionality the processes in the container are unaware, and unable to prevent or ignore the freeze command.
Run:
docker run -d --name testme alpine:3.8 /bin/sh -c 'sleep 10m'
This starts up a container using the tiny alpine Linux distribution. It uses the /bin/sh command ( a small version of /bin/bash ). It runs the sleep command ( doing nothing ) for 10 minutes. This gives us a running container that we can pause.
Run:
docker pause testme
Expected output
testme
docker pause showed the name of the container it just paused: testme
Run:
docker ps -a
Expected output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
637489e9b88d alpine:3.8 "/bin/sh -c 'sleep 1? 14 seconds ago Up 6 seconds (Paused) testme
Notice it is now in paused status.
If you run the command below you will get identical output list:
docker ps --filter status=paused
Let's attempt to remove this container. Run:
docker ps --filter status=paused | awk '{print $1}' | grep -v CONTAINER | xargs docker container rm
Expected output
Error response from daemon: You cannot remove a paused container 637489e9b88d5704b9e677ff26199a9fec41644d4310732943cab0a2c8b0d4a6. Unpause and then stop the container before attempting removal or force remove
Please read the output. Let's stop the container by running
docker stop testme
Expected output
testme
Shows testme got stopped.
When you have several paused containers you wish to stop, you can stop them all in one go using:
docker ps --filter status=paused | awk '{print $1}' | grep -v CONTAINER | xargs docker container stop
This will stop ALL containers in paused status.
Let's investigate if that worked. Run
docker ps --filter status=stopped
Expected output
Error response from daemon: Invalid filter 'status=stopped'
Obviously there is no stopped status. When you stop a container it goes into the exited status.
List of valid container statuses: created, restarting, running, removing, paused, exited, or dead
Let's investigate if that worked, this time using the correct status: exited. Run
docker ps --filter status=exited
Expected output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3e8fb9e2c41d alpine:3.8 "/bin/sh -c 'sleep 1? 3 minutes ago Exited (137) About a minute ago testme
Success. This is our list of currently exited containers. Let's pass this list of container IDs to docker container rm to remove these containers. Run
docker ps --filter status=exited | awk '{print $1}' | grep -v CONTAINER | xargs docker container rm
Expected output
3e8fb9e2c41d
Success. Our one exited container is now removed. You can run docker ps -a all by yourself and see this container no longer appears on the list.
Paused containers can be unpaused to start off at the exact place it got paused. A stopped container cannot be restarted at the exact place it got stopped. When you restart a container it starts at the beginning.
Summary: You cannot prune / remove a paused container - You have to unpause and then stop the container.
You already saw the hello world containers had to be manually removed / pruned.
If you run containers using the --rm option, the container is automatically removed when it exits
Let's get practical experience with this. Then you will probably always use the convenient --rm option.
Run these 3 commands to create 3 hello world containers:
docker run -d --rm hello-world
docker run -d --rm hello-world
docker run -d --rm hello-world
Let's check the list of containers using
docker ps -a
Expected output:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
No exited hello world containers shown. The --rm automatically removed those 3 containers when they exited. No cleanup needed.
Define these bash aliases. You can then use the second one for quick tests, saving you cleanup afterwards.
alias dr='docker run'
alias drrm='docker run --rm'
A bash alias is a shorter version of long shell commands. Its purpose is to avoid typing a long command.
This tutorial is now at its end.
Run these commands to remove all the images you will no longer be using.
docker image rm hello-world:latest
docker image rm nginx:mainline-alpine
docker image rm redis:alpine
docker image rm alpine:3.8
Maybe your development docker server is a mess.
Maybe ALL your containers should be stopped.
You can quickly do that using:
docker stop $(docker ps -a -q) #stop ALL containers
docker ps -a -q builds a list of all container IDs - running and exited.
It passes these IDs to docker stop.
ALL containers are stopped. No errors are shown for already exited containers.
To now remove all containers, run
docker rm -f $(docker ps -a -q) # remove ALL containers
Now you can experiment by applying container cleanup commands at your work.
Pro safety tip: always run a command to show you the selected list of containers to act upon. Only then run docker container rm to actually remove the containers.
grep, awk and xargs were used extensively in this tutorial. If you are not familiar with these tools you can now see it is really worthwhile to read some tutorials on it.
Multiplexing and Making Terminal Sessions Persistent with tmux
2,599 posts | 762 followers
FollowAlibaba Clouder - March 11, 2019
Alibaba Clouder - June 11, 2020
Alibaba Clouder - December 29, 2018
Alibaba Clouder - April 23, 2019
Alibaba Clouder - January 2, 2019
Alibaba Clouder - March 11, 2019
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