How to List Docker Containers

How to List Docker Containers

Reading time1 min
#Docker#Containers#CommandLine#DevOps

How to List Docker Containers

Running containers

docker ps

docker container ls is the same command under its newer, grouped name. Both show only running containers:

CONTAINER ID   IMAGE          COMMAND                  CREATED        STATUS        PORTS                  NAMES
3f2a9c1d7b44   nginx:stable   "/docker-entrypoint.…"   2 hours ago    Up 2 hours    0.0.0.0:8080->80/tcp   web

All containers, including stopped ones

docker ps -a

This adds containers in the Created and Exited states. If a container you just started is missing from docker ps, it most likely exited, and docker ps -a shows its exit code in the STATUS column. docker logs <name> tells you why.

Other useful flags:

docker ps -q            # IDs only, for scripts
docker ps -aq           # IDs of all containers
docker ps -l            # the most recently created container, any state
docker ps -n 5          # the last five created containers
docker ps --no-trunc    # full IDs and commands
docker ps -s            # add disk usage

With -s, the SIZE column shows the container's writable layer, and the virtual value in parentheses includes the read-only image layers. A large writable layer usually means the app writes logs or data inside the container instead of to a volume.

Filter the list

--filter (or -f) takes key=value pairs:

docker ps -a -f status=exited
docker ps -f name=api                  # name contains "api"
docker ps -f ancestor=nginx:stable     # created from this image
docker ps -f label=env=prod
docker ps -f publish=8080              # publishes port 8080
docker ps -f network=my-net
docker ps -f health=unhealthy
docker ps -a -f exited=137             # killed, often out of memory

Status values are created, running, paused, restarting, removing, exited and dead.

Filters with different keys must all match. Repeating the same key matches any of the values:

docker ps -a -f status=exited -f status=created     # exited OR created
docker ps -f name=api -f label=env=prod             # name matches AND label matches

The name filter matches substrings, so name=api also matches my-api-worker. For an exact match, anchor the regular expression. Docker stores names with a leading slash, so use -f name=^/api$.

Format the output

--format takes a Go template. With table you keep column headers:

docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}'
docker ps -a --format '{{.Names}}: {{.Status}}'
docker ps --format json

Available fields include .ID, .Image, .Command, .CreatedAt, .RunningFor, .Ports, .State, .Status, .Size, .Names, .Labels, .Label "key", .Mounts and .Networks.

To make a format the default, add it to ~/.docker/config.json:

{
  "psFormat": "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}"
}

JSON output works well with jq:

docker ps -a --format json | jq -r 'select(.State == "exited") | .Names'

Use it in scripts

Combine -q with filters to act on a set of containers:

# Stop everything created from an image
docker stop $(docker ps -q -f ancestor=my-app:1.0)

# Remove all stopped containers
docker container prune

docker container prune is safer than docker rm $(docker ps -aq), which tries to remove every container and fails on running ones. prune asks for confirmation and accepts filters, for example --filter until=24h to keep recent containers.

If the list can be empty, docker stop $(...) fails with a usage error. In scripts, use xargs -r (GNU) to skip the call when there is nothing to do:

docker ps -q -f label=job=nightly | xargs -r docker stop

Resource usage

docker ps shows state, not load. For CPU, memory and network per container:

docker stats                # live view
docker stats --no-stream    # one snapshot
docker stats --no-stream --format 'table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}'

Compose projects

Inside a Compose project directory, list only that project's containers:

docker compose ps
docker compose ps -a

Plain docker ps shows them too, with names like my-app-web-1. Compose also labels them, so docker ps -f label=com.docker.compose.project=my-app filters by project from anywhere.

When the list is empty but containers exist

  • Another daemon. docker ps talks to one daemon. Rootless Docker, Docker Desktop and a rootful system daemon each have their own containers. Check docker context ls and echo $DOCKER_HOST. With sudo docker ps you may be talking to a different daemon than without sudo.
  • Kubernetes nodes. Modern Kubernetes runs containers through containerd or CRI-O, not Docker. Use kubectl get pods or, on the node, sudo crictl ps.
  • Podman. Containers created with podman are listed by podman ps, not docker ps.

Quick reference

docker ps                                   # running
docker ps -a                                # all
docker ps -aq                               # all IDs
docker ps -a -f status=exited               # filter by state
docker ps -f name=api -f label=env=prod     # combine filters (AND)
docker ps --format 'table {{.Names}}\t{{.Status}}'
docker ps -s                                # sizes
docker stats --no-stream                    # resource usage
docker compose ps                           # current Compose project
docker container prune                      # remove stopped containers