1. Overview

Docker provides various options to list and filter containers in different states or even options to customize the list output.

In this tutorial, we're going to see how we can filter Docker containers in a variety of ways.

2. Listing Containers

In order to list the Docker containers, we can use the “docker ps” or “docker container ls” command. This command provides a variety of ways to list and filter all containers on a particular Docker engine.

Let's start by listing all the running containers.

2.1. Aliases

As of Docker 1.13, the Docker team regrouped every command to sit under the logical object it’s interacting with. For instance, in order to list Docker containers, in addition to “**docker ps”, we can use the “**docker container list” or even “**docker container ls” command.

All of these three aliases are supporting the same group of options. However, it's a good idea to adopt the new syntax.

2.2. Running Containers

*If we use the *“**docker container ls” command with no options, then it'll list all the running containers**:

$ docker container ls
CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS              PORTS                                NAMES
1addfea727b3        mysql:5.6            "docker-en.."   2 seconds ago       Up 1 second         0.0.0.0:32801->3306/tcp              dazzling_hellman
09c4105cb356        nats:2.1.0-scratch   "/nats-…"       17 minutes ago      Up 17 minutes       4222/tcp, 6222/tcp, 8222/tcp         nats-1
443fc0c41710        rabbitmq:3.7         "docker-…"      17 minutes ago      Up 17 minutes       4369/tcp, 5671-5672/tcp, 25672/tcp   rabbit-1
b06cfe3053e5        postgres:11          "docker-…"      29 minutes ago      Up 29 minutes       0.0.0.0:32789->5432/tcp              pg-2
4cf774b9e4a4        redis:5              "docker-…"      30 minutes ago      Up 30 minutes       0.0.0.0:32787->6379/tcp              redis-2

As shown above, we have five running containers so far — Nats, RabbitMQ, PostgreSQL, MySQL, and Redis.

By default, the output shows several details about each running container:

  • “CONTAINER ID” is the container unique identifier. This identifier is the truncated version of a pretty long SHA-256 hash
  • “IMAGE” is the container image name and its tag separated by a colon such as postgres:11
  • “COMMAND” is the command responsible for running the container
  • “CREATED” shows when the container was created
  • “STATUS” shows the container status. As mentioned above, all these containers are running
  • “PORTS” shows the port mappings between the host machine and inside the container. For instance, the “0.0.0.0:32789->5432/tcp” means that port 32789 in the host is mapped to port 5432 inside the container. Also, we can see that we didn't map any port for the Nats container — “4222/tcp, 6222/tcp, 8222/tcp”
  • “NAMES” represents the human-readable name of the Docker container, such as pg-2

By now, we should know about the meaning of each column. So, from now on, we'll only show a subset of these columns for the sake of brevity.

2.3. All Containers

By default, the “**docker container ls” command only shows the running containers. However, if we pass the -a or –all option, it'll list all (stopped and running) containers:

$ docker container ls -a
CONTAINER ID        IMAGE                STATUS
1addfea727b3        mysql:5.6            Up 4 hours
32928d81a65f        mysql:5.6            Exited (1) 4 hours ago
09c4105cb356        nats:2.1.0-scratch   Up 4 hours
443fc0c41710        rabbitmq:3.7         Up 4 hours
b06cfe3053e5        postgres:11          Up 4 hours
16d3c67ebd40        postgres:11          Exited (0) 4 hours ago
4cf774b9e4a4        redis:5              Up 4 hours
99c537a3dd86        redis:5              Exited (0) 4 hours ago

As shown above, we now have three containers that were stopped a few hours ago — Redis, MySQL, and PostgreSQL.

2.4. Latest Containers

To see the last n Docker containers (both running and stopped), we can use the -n or –last option:

$ docker container ls -n 2
CONTAINER ID        IMAGE               STATUS
1addfea727b3        mysql:5.6           Up 4 hours
32928d81a65f        mysql:5.6           Exited (1) 4 hours ago

It's also possible to see the latest container via the -l or –latest option:

$ docker container ls --latest
CONTAINER ID        IMAGE               STATUS
1addfea727b3        mysql:5.6           Up 4 hours

Of course, we can achieve the same thing with the -n 1 option.

2.5. Disabling Truncation

By default, Docker will truncate the output columns if their value is longer than some threshold. As a matter of fact, we already saw the truncated values for the container id.

Even though this is a good feature most of the time, we can disable it using the –no-trunc option:

$ docker container ls --latest --no-trunc
CONTAINER ID                                                       COMMAND
1addfea727b38f484a2e0023ed7f47dcb9bbfc6e053f094c349391bb38cb3af7   "docker-entrypoint.sh mysqld"

As shown above, the output columns are much more verbose now.

2.6. Quiet Mode

It's also possible to just see the container id of the containers. To do this, we can use the -q or –quiet option:

$ docker container ls -q
1addfea727b3
09c4105cb356
443fc0c41710
b06cfe3053e5
4cf774b9e4a4

We can mix and match options and see the full container identifiers:

$ docker container ls --quiet --no-trunc
1addfea727b38f484a2e0023ed7f47dcb9bbfc6e053f094c349391bb38cb3af7
09c4105cb3567ba0070dacf7381b9946165908c819c0841cffaa1855766537c7
443fc0c41710ee3811e72fe5079bf4696b9318e0754c38eeab1c960f5c5a7007
b06cfe3053e521704c67a1902a7302665ae05f66ef592419f32b8c73b2a066fd
4cf774b9e4a487a2ba658de37273994161378cffe7e69fe5c928ad29e6946372

The quiet mode can be especially useful when we're going to pass a collection of ids to another command. For instance, here's a way to force delete all containers:

$ docker container rm -f $(docker container ls -aq)

Of course, these sorts of combinations should be used with extreme caution.

2.7. Container Size

We can see the size of a container and its image on disk via the -s or –size options:

$ docker container ls --latest -s
CONTAINER ID        IMAGE               SIZE
1addfea727b3        mysql:5.6           2B (virtual 256MB)

The first value (2B) represents the number of bytes that are used for the writable layer of each container. The second value is the image size on disk, which is 256 MB in this case.

2.8. Customized Output

If we're not happy with the default output format, we can customize the output using the Go templates. All we have to do is to pass the desired format to the –format option. Let's see a quick example of this in action:

$ docker container ls --format "{{.ID}} -> Based on {{.Image}}, named {{.Names}}, ({{.Status}})"
1addfea727b3 -> Based on mysql:5.6, named dazzling_hellman, (Up 3 hours)
09c4105cb356 -> Based on nats:2.1.0-scratch, named nats-1, (Up 4 hours)
443fc0c41710 -> Based on rabbitmq:3.7, named rabbit-1, (Up 4 hours)
b06cfe3053e5 -> Based on postgres:11, named pg-2, (Up 4 hours)
4cf774b9e4a4 -> Based on redis:5, named redis-2, (Up 4 hours)

Here, we've used what is basically a templated string in the Go template format. The IDImageNames, and Status are placeholders, and the rest of the text is rendered as-is.

Moreover, it's possible to show the columns in a tabular format. We just have to use the table prefix:

$ docker container ls --format "table {{.ID}}\t{{.Image}}\t{{.Names}}"
CONTAINER ID        IMAGE                NAMES
1addfea727b3        mysql:5.6            dazzling_hellman
09c4105cb356        nats:2.1.0-scratch   nats-1
443fc0c41710        rabbitmq:3.7         rabbit-1
b06cfe3053e5        postgres:11          pg-2
4cf774b9e4a4        redis:5              redis-2

Let's take a closer look at the fields we can use in the template string:

  • .ID — the container id
  • .Image — the image name and tag
  • .Command — the command responsible for running this container
  • .CreatedAt — container creation time
  • .Running — the elapsed time since the container has started
  • .Ports — the port mapping
  • .Status — the container execution status
  • .Size — the container and its image disk-size
  • .Names — the container name
  • .Labels — all labels assigned to a container
  • .Mounts — the volumes for a container
  • .Networks — all network names attached to a container

2.9. Advanced Filtering

So far, we only filtered the containers based on running or stopped status. As it turns out, “**docker container ls” offers much more than this rudimentary filtering.

In order to filter the containers, we can use the -f or –filter option. For instance, here we're going to filter containers with the exited status:

$ docker container ls --filter "status=exited"
CONTAINER ID        IMAGE               STATUS
32928d81a65f        mysql:5.6           Exited (1) 8 hours ago
16d3c67ebd40        postgres:11         Exited (0) 9 hours ago
99c537a3dd86        redis:5             Exited (0) 9 hours ago

As shown above, we should pass the filter criteria with the key=value format.

If we want to apply multiple filters at the same time, we should pass multiple –filter options. For instance, we can go even further and only keep the exited containers with exit status equal to 1:

$ docker container ls --filter "status=exited" --filter "exited=1"
CONTAINER ID        IMAGE               STATUS
32928d81a65f        mysql:5.6           Exited (1) 8 hours ago

As we might expect, only MySQL now matches the filter criteria. The running or stopped are not the only Docker container states. As a matter of fact, if we, say, pause a Docker container:

$ docker container pause redis-2

Then we can filter all paused containers:

$ docker container ls --filter "status=paused"
CONTAINER ID        IMAGE               STATUS
4cf774b9e4a4        redis:5             Up 45 minutes (Paused)

Moreover, we can filter containers by any of the possible statuses — created, restarting, running, removing, paused, exited, or dead.

If we know some part of the container name, we can search for it:

$ docker container ls -a --filter "name=pg"
CONTAINER ID        IMAGE               STATUS
b06cfe3053e5        postgres:11         Up 18 minutes
16d3c67ebd40        postgres:11         Exited (0) 9 hours ago

We can also filter the containers based on their base image:

$ docker container ls -a --filter "ancestor=postgres"
CONTAINER ID        IMAGE               STATUS
b06cfe3053e5        postgres:11         Up 28 minutes
16d3c67ebd40        postgres:11         Exited (0) 9 hours ago

Here, we're only listing the containers that are based on the postgres image.

It's even possible to filter containers based on their creation time. For instance, here we're going to only keep the containers that are created before the Nats container:

$ docker container ls --filter "before=nats-1"
CONTAINER ID        IMAGE               STATUS
443fc0c41710        rabbitmq:3.7        Up 52 minutes
b06cfe3053e5        postgres:11         Up 52 minutes
4cf774b9e4a4        redis:5             Up 52 minutes (Paused)

On the other hand, we can list all the Docker containers created after the Nats one using the since filter:

$ docker container ls --filter "since=nats-1"
CONTAINER ID        IMAGE               STATUS
2fdc65a6effb        mysql:5.6           Exited (137) 4 days ago
1addfea727b3        postgres:11         Exited (0) 3 days ago

3. Conclusion

In this tutorial, we saw how to list and filter Docker containers using the “docker container ls” command and its useful options.

For a more detailed discussion, it's always a good idea to check out the official documentation.