docker ps and Container Status
docker ps lists containers known to the Docker daemon, especially the ones currently running. It matters because containers are not just images on disk: each container has a lifecycle, a main process, runtime configuration, a writable layer, logs, ports, names, and an exit status. Reading docker ps well is the first troubleshooting skill for running containers.
The modern long form is docker container ls, while docker ps remains the short, widely used alias. Both commands ask Docker for container metadata and print a table that tells you what is running, what command started it, how long it has been up, what ports are published, and what name Docker assigned.
Overview: How Container Listing Works
A Docker image is a read-only template made from filesystem layers and configuration. A container is an instance of that image with its own metadata, runtime settings, and thin writable layer. When the container is running, Docker also tracks the main process created from the image command plus any overrides you passed to docker run.
docker ps does not scan your shell processes directly. The Docker CLI sends an API request to the Docker daemon. The daemon reads its container database and runtime state, then returns rows to the CLI. On Docker Desktop for macOS and Windows, Linux containers actually run inside Docker’s managed Linux VM, so docker ps is reporting containers inside that VM. On native Linux, the daemon reports containers managed on that host.
By default, docker ps shows only running containers. Stopped containers are still real containers: they keep their name, configuration, logs, exit code, and writable layer until you remove them with docker rm or a prune command. To see both running and stopped containers, use docker ps -a or docker container ls --all.
The STATUS column is a human-readable summary of lifecycle state. Common values include Up for a running container, Exited for a stopped container, Created for a container that exists but has not started, Restarting when a restart policy is repeatedly starting it, and Paused when execution is suspended. For exact machine-readable details, use docker inspect; docker ps is optimized for fast reading.
Syntax
docker ps [OPTIONS]
docker container ls [OPTIONS]
| Option or column | Meaning |
|---|---|
CONTAINER ID |
A shortened unique ID. It is convenient for commands, but container names are clearer for humans. |
IMAGE |
The image reference used to create the container, such as nginx:1.27-alpine. |
COMMAND |
The main command configured by the image or overridden at docker run time. Long commands are truncated by default. |
CREATED |
When the container object was created, not necessarily how long it has been running. |
STATUS |
A readable state summary such as Up 2 minutes or Exited (0) 10 seconds ago. |
PORTS |
Published host port mappings and exposed-port metadata. Only -p or Compose ports: publishes a port to the host. |
NAMES |
The container name. Docker generates one if you do not pass --name. |
-a or --all |
Show all containers, including stopped containers. |
-q or --quiet |
Print only container IDs. Useful for scripts. |
-f or --filter |
Filter by fields such as status=exited, name=web, ancestor=nginx:1.27-alpine, or label=env=dev. |
--format |
Render selected fields with a Go template, often as a custom table. |
--no-trunc |
Show full IDs and commands instead of shortened values. |
-l or --latest |
Show only the latest created container. |
-n or --last |
Show the last N created containers, whether running or stopped. |
-s or --size |
Include writable-layer and virtual size information. |
Examples
Example 1: Start a Container and List Running Containers
docker run -d --name web-ps -p 8080:80 nginx:1.27-alpine
docker ps
Output:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b8d3f4a91c2e nginx:1.27-alpine "/docker-entrypoint...." 5 seconds ago Up 4 seconds 0.0.0.0:8080->80/tcp web-ps
docker run -d starts Nginx in detached mode so your terminal returns immediately. The -p 8080:80 option publishes host port 8080 to container port 80. The PORTS column shows that mapping. If an image contains EXPOSE 80, that is only metadata; the host port appears here because -p published it.
Example 2: Include Stopped Containers
docker stop web-ps
docker ps
docker ps -a
Output:
web-ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b8d3f4a91c2e nginx:1.27-alpine "/docker-entrypoint...." 2 minutes ago Exited (0) 12 seconds ago web-ps
After docker stop, the container is no longer running, so plain docker ps shows no rows. docker ps -a includes stopped containers and shows Exited (0). Exit code 0 usually means the main process shut down successfully. A nonzero code often means an error, but you should confirm with docker logs and docker inspect.
Example 3: Filter for Containers That Need Attention
docker ps -a --filter "status=exited" --filter "name=web"
Output:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b8d3f4a91c2e nginx:1.27-alpine "/docker-entrypoint...." 3 minutes ago Exited (0) 45 seconds ago web-ps
Filters are combined, so this command shows containers that are both stopped and whose name matches web. This is safer than visually scanning a long list. Common filters include status=running, status=exited, ancestor=redis:7.2-alpine, label=com.example.team=platform, and publish=8080.
Example 4: Format Output for Scripts
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}"
Output:
NAMES IMAGE STATUS PORTS
web-ps nginx:1.27-alpine Up 10 seconds 0.0.0.0:8080->80/tcp
--format avoids fragile parsing of the default spacing. Docker provides fields such as .ID, .Names, .Image, .Command, .RunningFor, .Status, .Ports, and .Size. For automation that needs only IDs, docker ps -q is even simpler.
How It Works Step by Step
- You run
docker psordocker container ls. - The CLI contacts the Docker daemon through the Docker API. Depending on the platform, that connection may use a Unix socket, named pipe, or configured remote endpoint.
- The daemon reads container metadata: IDs, names, image references, commands, creation times, network settings, labels, size data when requested, and runtime state.
- By default, the daemon returns only containers in a running state. With
--all, it also returns created, exited, paused, dead, and restarting containers. - Filters are applied to the container set. Formatting happens after Docker has selected the rows.
- The CLI truncates long IDs and commands unless you use
--no-trunc, then prints the table or custom template output.
The key internal idea is that Docker tracks containers separately from images. Stopping a container stops its main process, but it does not delete the container object. Removing a container does not remove its image. Removing an image usually requires that no container still references it.
Common Mistakes
Assuming docker ps Shows Everything
docker ps
Plain docker ps shows only running containers. If your container started and immediately exited, it will disappear from this view and beginners often think Docker never created it. Use this when troubleshooting:
docker ps -a
Confusing Created Time with Uptime
docker ps -a --format "table {{.Names}}\t{{.CreatedAt}}\t{{.Status}}"
CREATED means when the container object was created. STATUS tells you whether it is currently up and for how long, or when it exited. A container can be created yesterday, restarted today, and show Up 3 minutes. Use STATUS for runtime state, not CREATED.
Thinking EXPOSE Publishes a Port
docker run -d --name hidden-nginx nginx:1.27-alpine
docker ps --filter "name=hidden-nginx"
Output:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f2c742e10a14 nginx:1.27-alpine "/docker-entrypoint...." 8 seconds ago Up 7 seconds 80/tcp hidden-nginx
The PORTS column may show 80/tcp, but that does not mean your host can reach it on port 80. It means the image exposes port 80 as metadata. Publish a host port explicitly when you need host access:
docker rm -f hidden-nginx
docker run -d --name visible-nginx -p 8080:80 nginx:1.27-alpine
Best Practices
- Use
docker container lsin formal documentation if you want the modern long form, and recognizedocker psas the common short form. - Start troubleshooting with
docker ps -awhen a container is missing from the running list. - Name important containers with
--nameso listings and logs are readable. - Use specific image tags such as
nginx:1.27-alpineinstead of relying onlatest, which can move over time. - Use
--filterto narrow long lists by status, name, image ancestor, label, or published port. - Use
--formator-qfor scripts instead of parsing the default table spacing. - Use
--no-truncwhen the exact command or full container ID matters. - Remember that stopped containers still consume names and can hold logs and writable-layer data until removed.
- Use
docker logsanddocker inspectafterdocker pstells you which container needs investigation.
Practice Exercises
- Run
nginx:1.27-alpinein detached mode with the namepractice-weband publish host port 8081 to container port 80. Then list only running containers and confirm the port mapping appears. - Stop
practice-web, then use a command that shows stopped containers. Expected end state: the status starts withExited. - Use
--formatto print a table containing only container names, images, and status. Hint: use the fields.Names,.Image, and.Status.
Summary
docker psanddocker container lslist containers managed by the Docker daemon.- Plain
docker psshows running containers only; add-ato include stopped containers. - The
STATUScolumn is the fastest way to see whether a container is up, exited, paused, restarting, or only created. - Containers are separate from images. Stopping or removing one does not automatically remove the other.
- The
PORTScolumn distinguishes published host mappings like0.0.0.0:8080->80/tcpfrom exposed metadata like80/tcp. - Filters and formatted output make
docker pspractical for real projects and scripts.
