×
Community Blog Docker Container Cleanup Tutorial

Docker Container Cleanup Tutorial

This tutorial gives you practical experience in cleaning up Docker containers on Alibaba Cloud.

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. )

Preparation

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

Remove Containers Using Docker Container Prune

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.

Prune containers using labels

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.

Docker ps Filtering Reference

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" __

Prune Containers Using Exit Status

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.

Remove Containers in Status: Created

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.

Remove Containers in Status: Paused

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.

Remove the Container When It Exits

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.

Tutorial Cleanup

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

Overall Docker Cleanup

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

Summary

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.

0 0 0
Share on

Alibaba Clouder

2,599 posts | 762 followers

You may also like

Comments