How would you list Docker containers that are not currently running, and then narrow that list to ones matching a particular label, name pattern, or image?
answer
- docker ps = running only; -a = all states
- --filter status=exited / exited=137 / health=unhealthy
- label= and ancestor= for grouping
- -q for IDs to pipe; --format 'table {{.Names}}\t{{.Status}}'
- Prefer .State over .Status in scripts
basics
~10 sdocker ps shows only running containers; docker ps -a shows all states. Narrow with --filter: status=exited, label=team=payments, name=api, ancestor=nginx:alpine. Add -q for IDs only and --format for custom columns.
solid answer
~50 s`docker ps` lists **running** containers only — the single most common surprise. `docker ps -a` (or `--all`) includes `created`, `exited`, `paused`, `dead` and everything else. Filtering uses repeatable `--filter key=value` (short `-f`) flags, which combine with AND across different keys and OR within repeats of the same key: - `--filter status=exited` (also `created`, `running`, `paused`, `restarting`, `removing`, `dead`) - `--filter exited=1` — containers whose recorded exit code was 1 - `--filter name=api` — substring/regex match on the name - `--filter ancestor=nginx:alpine` — containers created from that image - `--filter label=team=payments` or just `--filter label=canary` - `--filter health=unhealthy`, `--filter before=<c>` / `since=<c>` Shape the output with `--format` (a Go template) and `-q/--quiet` for bare IDs, which pipes straight into other commands. `-s` adds a size column, `-n 5` shows the last five, `-l` the latest. A typical cleanup one-liner is `docker ps -aq --filter status=exited | xargs -r docker rm`.
code
bash · 5 linesdocker ps -a
docker ps -a --filter status=exited --format 'table {{.Names}}\t{{.Status}}\t{{.Image}}'
docker ps -a --filter label=team=payments --filter status=exited -q
docker ps --filter health=unhealthy
docker ps -a --filter ancestor=nginx:alpinego deeper
Know docker ps versus docker ps -a, and at least --filter status=exited plus -q for piping.
Use the wider filter set (label, ancestor, health, exited code) and --format templates rather than parsing text.
Build repeatable operational sweeps — unhealthy containers, exit-137 fleets, label-scoped cleanup — and script against .State or docker inspect.
Insist on labeling conventions so containers are groupable by team, service and environment without fragile name matching.
## Why `docker ps -a` matters By default `docker ps` lists only containers in the `running` state. Containers that were created but never started, or that exited seconds ago, are invisible — which is why "my container disappeared" is almost always "my container exited and I did not pass `-a`". `docker ps -a` shows every container object regardless of state, and is the right first command when something is not behaving as expected. The default columns are CONTAINER ID, IMAGE, COMMAND, CREATED, STATUS, PORTS, NAMES. STATUS carries the state plus context: `Up 4 hours`, `Up 2 minutes (healthy)`, `Up 10 seconds (Paused)`, `Exited (137) 3 minutes ago`, `Restarting (1) 5 seconds ago`, `Created`. ## Filters `--filter`/`-f` takes `key=value` and may be repeated. Different keys are ANDed; repeats of the same key are ORed. The commonly used keys: | Filter | Meaning | |---|---| | `status=<state>` | one of created, restarting, running, removing, paused, exited, dead | | `exited=<int>` | containers whose recorded exit code equals this | | `name=<pattern>` | matches on container name (substring / regex) | | `id=<pattern>` | matches on container ID | | `ancestor=<image>` | containers created from an image, tag, or ID — including descendants of that image | | `label=<key>` or `label=<key>=<value>` | matches container labels | | `health=starting\|healthy\|unhealthy\|none` | current health-check state | | `before=<c>` / `since=<c>` | created before/after the named container | | `volume=<name>` / `network=<name>` | containers attached to a volume or network | | `publish=<port>` / `expose=<port>` | containers publishing or exposing a port | ## Shaping output `--format` takes a Go template over the container struct, with a `table` prefix to get a header row: ``` docker ps -a --format 'table {{.Names}}\t{{.Status}}\t{{.Image}}' docker ps -a --format '{{.Names}} {{.Status}}' docker ps --format json ``` Useful fields: `.ID`, `.Names`, `.Image`, `.Command`, `.CreatedAt`, `.RunningFor`, `.Status`, `.State`, `.Ports`, `.Labels`, `.Label "key"`, `.Size`, `.Mounts`, `.Networks`. Other flags: `-q/--quiet` prints IDs only (the piping workhorse), `--no-trunc` prints full IDs and commands, `-s/--size` adds the writable-layer size, `-n <int>` shows the last n containers of any state, `-l/--latest` the most recent one. `.State` gives you the raw lowercase state word while `.Status` gives the human string — prefer `.State` when scripting. For anything beyond listing, `docker inspect` with a `-f` template is the machine-readable source of truth. ## Compositions worth memorizing ```bash # every exited container, oldest details included docker ps -a --filter status=exited --format 'table {{.Names}}\t{{.Status}}' # remove all stopped containers docker ps -aq --filter status=exited | xargs -r docker rm # anything unhealthy right now docker ps --filter health=unhealthy # everything from one image, across states docker ps -a --filter ancestor=myorg/api:1.4 # containers a team owns, by label docker ps -a --filter label=team=payments -q # containers that failed with a specific code docker ps -a --filter exited=137 ``` That last one is a nice diagnostic sweep: exit 137 means SIGKILL, so a fleet-wide list of `exited=137` containers surfaces both OOM kills and services that never handled their stop signal. ## A note on labels Labels (`docker run --label team=payments`, or `LABEL` in a Dockerfile, or `labels:` in Compose) are the intended mechanism for grouping containers in ad-hoc operations. Filtering by name substring works but is fragile; labels are explicit and survive renames. Compose sets its own labels (project, service) automatically, which is how `docker compose ps` scopes its view.
- Why does `docker ps` not show a container you just ran, even though the command appeared to succeed?Because `docker ps` lists only running containers, and the container almost certainly exited immediately — a short-lived command, a crash on startup, or a missing TTY for an interactive shell. Run `docker ps -a` to see it with its exit code in the STATUS column, then `docker logs <name>` to see why.
- When scripting against `docker ps --format`, why prefer `.State` over `.Status`?`.Status` is a human-facing string like `Exited (137) 3 minutes ago` or `Up 2 minutes (healthy)`, whose wording and timing text change; parsing it is brittle. `.State` is the bare lowercase state word — `running`, `exited`, `paused` — which is stable. For anything richer, `docker inspect -f` over the full container JSON is the reliable source.
saying these in an interview costs you the question
- Believing `docker ps` lists all containers by default
- Grepping the STATUS text instead of using `--filter status=`
- Not knowing `-q` exists and copy-pasting IDs by hand
- Thinking `--filter` values are ANDed even when the same key repeats (repeats are ORed)
- Filtering by name substring when labels would be the stable grouping