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

  1. You run docker ps or docker container ls.
  2. 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.
  3. The daemon reads container metadata: IDs, names, image references, commands, creation times, network settings, labels, size data when requested, and runtime state.
  4. By default, the daemon returns only containers in a running state. With --all, it also returns created, exited, paused, dead, and restarting containers.
  5. Filters are applied to the container set. Formatting happens after Docker has selected the rows.
  6. 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 ls in formal documentation if you want the modern long form, and recognize docker ps as the common short form.
  • Start troubleshooting with docker ps -a when a container is missing from the running list.
  • Name important containers with --name so listings and logs are readable.
  • Use specific image tags such as nginx:1.27-alpine instead of relying on latest, which can move over time.
  • Use --filter to narrow long lists by status, name, image ancestor, label, or published port.
  • Use --format or -q for scripts instead of parsing the default table spacing.
  • Use --no-trunc when 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 logs and docker inspect after docker ps tells you which container needs investigation.

Practice Exercises

  1. Run nginx:1.27-alpine in detached mode with the name practice-web and publish host port 8081 to container port 80. Then list only running containers and confirm the port mapping appears.
  2. Stop practice-web, then use a command that shows stopped containers. Expected end state: the status starts with Exited.
  3. Use --format to print a table containing only container names, images, and status. Hint: use the fields .Names, .Image, and .Status.

Summary

  • docker ps and docker container ls list containers managed by the Docker daemon.
  • Plain docker ps shows running containers only; add -a to include stopped containers.
  • The STATUS column 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 PORTS column distinguishes published host mappings like 0.0.0.0:8080->80/tcp from exposed metadata like 80/tcp.
  • Filters and formatted output make docker ps practical for real projects and scripts.