List and Filter Podman Containers with `podman ps`

Tested on Red Hat Enterprise Linux 10.2 (Coughlan)
Package podman-5.8.2-5.el10_2.x86_64
Applies to Any Linux host with Podman installed
Privilege Rootful examples on the lab host; flags behave the same rootless unless noted
Scope Finding and listing containers with podman ps — default listing, -a, quiet IDs, --filter, --format, --sort, --size, --pod, --ns, --external, --sync, and --watch. Does not cover podman inspect field reference, container lifecycle commands, pod management, or system-wide storage accounting.
Related guides Run containers with podman run
Install Podman on RHEL
What is Podman?

podman ps shows what is running, which image each container uses, and which ports are published. This guide covers listing and filtering only — not lifecycle commands or full inspect JSON.

The lab uses ps-web (nginx), ps-api and ps-vol-c (sleep containers), ps-exited and ps-label-demo (stopped), ps-created (never started), and ps-pod-c1 in pod ps-web-pod.


List running Podman containers

A plain podman ps shows only containers whose main process is currently running:

bash
podman ps

Sample output:

output
CONTAINER ID  IMAGE                                               COMMAND               CREATED             STATUS             PORTS                  NAMES
e396d532706f                                                                            About a minute ago  Up About a minute                         339b450a86e4-infra
f1e749ebb335  docker.io/library/nginx:alpine                      nginx -g daemon o...  About a minute ago  Up About a minute  0.0.0.0:18080->80/tcp  ps-web
0945a2fed023  registry.access.redhat.com/ubi9/ubi-minimal:latest  sleep 600             About a minute ago  Up About a minute                         ps-api
15fdaaced09a  registry.access.redhat.com/ubi9/ubi-minimal:latest  sleep 600             About a minute ago  Up About a minute                         ps-pod-c1
ef3ddb3b3d16  registry.access.redhat.com/ubi9/ubi-minimal:latest  sleep 600             54 seconds ago      Up 53 seconds                             ps-vol-c

Each row includes container ID, image, command, created time, status, ports, and name. The 339b450a86e4-infra row is the pod infra container for ps-web-pod.

Equivalent spellings:

text
podman ps
podman container ps
podman container ls
podman container list

This article sticks with podman ps as the primary form.


List all containers including stopped ones

Add -a (or --all) when you need containers that are not running:

bash
podman ps -a

Sample output:

output
CONTAINER ID  IMAGE                                               COMMAND               CREATED             STATUS                         PORTS                  NAMES
e396d532706f                                                                            About a minute ago  Up About a minute                                     339b450a86e4-infra
f1e749ebb335  docker.io/library/nginx:alpine                      nginx -g daemon o...  About a minute ago  Up About a minute              0.0.0.0:18080->80/tcp  ps-web
0945a2fed023  registry.access.redhat.com/ubi9/ubi-minimal:latest  sleep 600             About a minute ago  Up About a minute                                     ps-api
75f5f4d727b7  registry.access.redhat.com/ubi9/ubi-minimal:latest  echo exited-once      About a minute ago  Exited (0) About a minute ago                         ps-exited
c22122d22ea8  registry.access.redhat.com/ubi9/ubi-minimal:latest  sleep 600             About a minute ago  Created                                               ps-created
75cfc331af02  registry.access.redhat.com/ubi9/ubi-minimal:latest  sh -c exit 1          About a minute ago  Exited (1) About a minute ago                         ps-label-demo
15fdaaced09a  registry.access.redhat.com/ubi9/ubi-minimal:latest  sleep 600             About a minute ago  Up About a minute                                     ps-pod-c1
ef3ddb3b3d16  registry.access.redhat.com/ubi9/ubi-minimal:latest  sleep 600             55 seconds ago      Up 54 seconds                                         ps-vol-c

Eight rows appear here instead of five. ps-exited and ps-label-demo show Exited with an exit code; ps-created shows Created because nothing started it yet.

Without -a, those rows disappear:

bash
podman ps

Scripts that clean up old containers usually start from podman ps -a or podman ps -aq.

Status strings you may see:

  • Created — container exists but the main process has not started
  • Up — running (often with a duration, such as Up 2 minutes)
  • Exited (N) — main process finished; N is the exit code
  • Paused — cgroup frozen with podman pause
  • Stopping — shutdown in progress
  • Unknown — state could not be reconciled with the runtime (see --sync below)

Show only container IDs

Quiet mode prints IDs one per line, which is easier to feed into other tools:

bash
podman ps -q

Sample output:

output
e396d532706f
f1e749ebb335
0945a2fed023
15fdaaced09a
ef3ddb3b3d16

Those IDs match the five running rows above.

Add -a for stopped and created containers:

bash
podman ps -aq

That returns eight IDs on this host.

You can stop every running container with substitution:

bash
podman stop $(podman ps -q)

That stops every running container, including infra containers you may want to keep. Prefer filters or native flags instead:

bash
podman container stop --all

Many subcommands accept -a or --filter directly, so shell substitution is not always necessary.


Filter containers with podman ps --filter

--filter (or -f) accepts key=value conditions. Most filters need podman ps -a when the target container is not running.

Filter by status

List containers that have fully stopped:

bash
podman ps -a --filter status=exited --format "{{.Names}} {{.Status}}"

Sample output:

output
ps-exited Exited (0) 2 minutes ago
ps-label-demo Exited (1) 2 minutes ago

Both exited workloads appear; running and Created rows are omitted.

Filter by name

Name filters match substrings. A filter of name=web finds ps-web:

bash
podman ps --filter name=web --format "{{.Names}}"

Sample output:

output
ps-web

Filter by label

Labels set at podman run time are filterable. The nginx container carries app=frontend:

bash
podman ps --filter label=app=frontend --format "{{.Names}}"

Sample output:

output
ps-web

Filter by image or ancestor

ancestor= matches containers created from an image reference (name, tag, or ID):

bash
podman ps -a --filter ancestor=registry.access.redhat.com/ubi9/ubi-minimal --format "{{.Names}}"

Sample output:

output
ps-api
ps-exited
ps-created
ps-label-demo
ps-pod-c1
ps-vol-c

The nginx container is excluded because it came from a different image.

Filter by network

When a container is attached to a user-defined network, you can list it by network name:

bash
podman ps --filter network=ps-net-demo --format "{{.Names}}"

Sample output:

output
ps-vol-c

Only ps-vol-c was started with --network ps-net-demo in this lab.

Filter by volume

Similarly, volume= matches containers that mount a named volume:

bash
podman ps --filter volume=ps-vol-data --format "{{.Names}}"

Sample output:

output
ps-vol-c

Filter by pod

Pod membership is a first-class filter. This lists containers in pod ps-web-pod:

bash
podman ps --filter pod=ps-web-pod --format "{{.Names}}"

Sample output:

output
339b450a86e4-infra
ps-pod-c1

The infra container and the workload container inside the pod both match.

Filter by exit code

After a container exits, exited=N matches containers that stopped with that code:

bash
podman ps -a --filter exited=1 --format "{{.Names}} {{.State}}"

Sample output:

output
ps-label-demo exited

ps-label-demo was started with sh -c exit 1, so only it matches exited=1.

Filter containers that should start on boot

On hosts using systemd or Quadlet integration, some containers are marked to start at boot:

bash
podman ps -a --filter should-start-on-boot=true --format "{{.Names}}"

An empty result is normal when no container is marked for boot start.


Combine multiple podman ps filters

Repeat --filter to narrow results. Podman combines filters with these rules:

  • Filters with different keys are ANDed
  • Repeated filters with the same key are generally ORed
  • label is the exception — repeated label filters are ANDed

Different keys must all match:

bash
podman ps -a --filter status=exited --filter label=app=demo --format "{{.Names}} {{.Status}}"

Sample output:

output
ps-label-demo Exited (1) 3 minutes ago

ps-exited also has status=exited, but it lacks app=demo, so it drops out. ps-label-demo matches both filters.

The same key ORs values — for example, status=running and status=paused lists containers in either state, not both at once:

bash
podman ps --filter status=running --filter status=paused --format "{{.Names}} {{.Status}}"

Run combined filters and read the result rather than assuming a single global AND/OR rule for every key.


Format podman ps output

--format uses Go templates. A table prefix builds column headers from tab-separated fields:

bash
podman ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"

Sample output:

output
NAMES               IMAGE                                               STATUS
339b450a86e4-infra                                                      Up 3 minutes
ps-web              docker.io/library/nginx:alpine                      Up 3 minutes
ps-api              registry.access.redhat.com/ubi9/ubi-minimal:latest  Up 3 minutes
ps-pod-c1           registry.access.redhat.com/ubi9/ubi-minimal:latest  Up 3 minutes
ps-vol-c            registry.access.redhat.com/ubi9/ubi-minimal:latest  Up 2 minutes

Omit table when you want a single field per line — useful for scripts:

bash
podman ps --format "{{.Names}}"

Sample output:

output
339b450a86e4-infra
ps-web
ps-api
ps-pod-c1
ps-vol-c

Practical template fields for listing work include:

  • .ID — short container ID
  • .Names — container name
  • .Image — image reference
  • .Status — human-readable uptime or exit phrase
  • .State — state keyword (running, exited, created, …)
  • .Ports — published port mapping
  • .Networks — attached networks
  • .PodName — pod name when the container belongs to a pod
  • .Restarts — restart count when a restart policy is in use
  • .Pid — main process PID on the host (running containers)

JSON output uses the same flag:

bash
podman ps --format json

That prints a JSON array of summary objects for quick scripts.

podman ps --format lists selected summary fields across containers; Inspect containers with podman inspect returns full configuration and state for one object. Use format for dashboards and loops; use inspect for mount lists, label maps, or network settings on a single target.


Sort Podman containers

--sort orders rows before printing. Sort keys include created, id, image, names, runningfor, size, status, and command.

Sort alphabetically by name across all containers:

bash
podman ps -a --sort names --format "{{.Names}} {{.Status}}"

Sample output:

output
339b450a86e4-infra Up 4 minutes
ps-api Up 4 minutes
ps-created Created
ps-exited Exited (0) 4 minutes ago
ps-label-demo Exited (1) 4 minutes ago
ps-pod-c1 Up 4 minutes
ps-vol-c Up 4 minutes
ps-web Up 4 minutes

Use runningfor for uptime order or created for age order.


Display container size

--size adds writable-layer size to the listing. Calculating size takes extra work, so this mode is slower than a plain table:

bash
podman ps -a --size --format "table {{.Names}}\t{{.Size}}"

Sample output:

output
NAMES               SIZE
339b450a86e4-infra  0B (virtual 0B)
ps-web              235kB (virtual 64.4MB)
ps-api              233kB (virtual 109MB)
ps-exited           233kB (virtual 109MB)
ps-created          0B (virtual 109MB)
ps-label-demo       233kB (virtual 109MB)
ps-pod-c1           233kB (virtual 109MB)
ps-vol-c            234kB (virtual 109MB)

The first number is the container writable layer; virtual includes the image size underneath. That is per-container filesystem cost, not a full storage report. For reclaimable space across images, volumes, and containers, see Podman system prune and system df.


Display pod information

--pod adds pod ID and pod name columns:

bash
podman ps --pod --format "table {{.Names}}\t{{.Pod}}\t{{.PodName}}"

Sample output:

output
NAMES               POD ID        PODNAME
339b450a86e4-infra  339b450a86e4  ps-web-pod
ps-web                            
ps-api                            
ps-pod-c1           339b450a86e4  ps-web-pod
ps-vol-c

Containers outside a pod leave the pod columns blank. ps-pod-c1 shares ps-web-pod with its infra container.

You can combine --pod with --filter pod=NAME (shown earlier) to focus on one pod without extra columns. Pod creation and multi-container layouts belong in Podman pods — this section only reads pod metadata from the list.


Display container namespace information

--ns adds Linux namespace IDs for debugging and correlation with host tools:

bash
podman ps -a --ns --format "table {{.Names}}\t{{.IPC}}\t{{.NET}}\t{{.PIDNS}}"

Sample output:

output
NAMES               IPC         NET         PIDNS
339b450a86e4-infra  4026532747  4026532679  4026532748
ps-web              4026532605  4026532496  4026532606
ps-api              4026532676  4026532608  4026532677
ps-exited                                   
ps-created

Running containers show numeric namespace identifiers; stopped rows may leave columns empty because namespaces are torn down after exit. How Podman maps those namespaces to conmon, crun, and networking is covered in Podman architecture — not repeated here.


Show external containers in shared storage

Podman shares storage with tools such as Buildah. Working containers from those tools may not appear in a default listing.

Create a Buildah working container to demonstrate:

bash
buildah from --name ps-buildah-demo registry.access.redhat.com/ubi9/ubi-minimal

Buildah prints the container ID when the working container is ready.

A normal podman ps -a does not show that Buildah container:

bash
podman ps -a | grep buildah || echo "(no buildah rows in default ps)"

Sample output:

output
(no buildah rows in default ps)

Add --external to include storage Podman does not own:

bash
podman ps -a --external --format "table {{.ID}}\t{{.Names}}\t{{.Status}}\t{{.Command}}"

Sample output:

output
ID           NAMES             STATUS     COMMAND
cd8803fa938f ps-buildah-demo   Storage    buildah

Status Storage and command buildah mark shared-storage entries that Podman did not start as ordinary runtime containers.

Remove the demo working container when you are done:

bash
buildah rm ps-buildah-demo

Refresh container state with --sync

If status looks wrong compared to crun or process inspection, --sync forces Podman to reconcile with the OCI runtime before printing:

bash
podman ps --sync --format "{{.Names}} {{.Status}}"

Sample output:

output
339b450a86e4-infra Up 6 minutes
ps-web Up 6 minutes
ps-api Up 6 minutes
ps-pod-c1 Up 6 minutes
ps-vol-c Up 5 minutes

Reserve --sync for stale-state troubleshooting, not everyday listing.


Watch the container list

--watch reprints the table on an interval (seconds). This is useful when you are waiting for a container to appear or exit:

bash
podman ps --watch 2

Podman redraws the table every two seconds until you press Ctrl+C.


podman ps vs podman inspect

Need Command
List running containers podman ps
List stopped and running podman ps -a
Search many containers podman ps --filter
Extract summary fields podman ps --format
Detailed object configuration and state podman inspect

Use the list commands above to find containers; reach for podman inspect when one target needs full JSON detail.


References


Summary

podman ps is the default view of running containers on a Linux host. With -a you also see stopped and created instances, which is essential when exit codes or cleanup matter. Quiet mode (-q / -aq) feeds IDs into scripts; native flags such as podman container stop --all are often safer than blind $(podman ps -q) substitution.

On busy hosts, --filter narrows by status, name, label, image, network, volume, pod, and exit code, and you can stack filters to match several conditions at once. --format and --sort reshape the table for operators and automation without pulling full inspect JSON. --size, --pod, --ns, and --external add filesystem cost, pod membership, namespace IDs, and shared-storage entries that a plain listing omits.

When one container needs full configuration detail, switch to podman inspect instead of stretching ps --format. Identify targets with the list commands here first; then follow the pod and system-storage guides for layout and reclaim work at scale.

Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, networking, and security, delivering robust and efficient solutions for diverse projects.

  • Go (programming language)
  • Python (programming language)
  • DevOps
  • Computer Security
  • Cloud Computing
  • Kubernetes
  • Linux
  • Ansible (software)