| |

Docker 6 🐳 Docker CLI Core Commands: docker run, docker ps, docker stop, docker rm

The Docker CLI is the primary interface for managing containers. Four commands form the core of daily container work: docker run creates and starts a container from an image, docker ps lists containers and their states, docker stop gracefully terminates a running container, and docker rm removes a container from the system. These four operations cover the essential lifecycle of any containerized process, and understanding their options and interactions is the foundation of working with Docker effectively.

Each command has flags that modify its behavior, and the combinations matter. docker run -d starts a container in the background; docker run -it attaches an interactive terminal. docker ps -a shows stopped containers as well as running ones. docker stop sends SIGTERM and waits before sending SIGKILL. docker rm fails on a running container unless forced, which is a deliberate safety mechanism. Knowing when and how to use each flag prevents the common frustrations of orphaned containers, lost data, and containers that cannot be removed.

This chapter covers the syntax and options of docker run, docker ps, docker stop, and docker rm, the lifecycle states of a container, the patterns for cleaning up containers, and the pitfalls that arise from misusing these commands.

Key point: docker run creates and starts a container, docker ps lists containers, docker stop gracefully stops a running container, and docker rm removes a stopped container. These four commands form the container lifecycle: create, list, stop, remove.


Why these four commands matter

The container lifecycle. A container moves through states: created, running, paused, stopped, and removed. docker run moves it from created to running. docker stop moves it from running to stopped. docker rm moves it from stopped to removed. docker ps reports which state a container is in. Every other Docker command operates on containers in one of these states.

The ephemeral nature of containers. A container’s writable layer is ephemeral. Removing the container removes the layer and any data written to it unless that data is in a volume. This makes the distinction between stopping and removing critical: docker stop preserves the container and its data for later restart, while docker rm destroys the container and its writable layer.

The resource management problem. Containers consume disk space, memory, and CPU. Stopped containers still occupy disk space. Orphaned containers accumulate over time. Regular cleanup with docker rm and docker container prune keeps the system from filling with dead containers.

The debugging problem. When a container fails, the first step is often to check its status with docker ps -a and its logs with docker logs. Understanding the container’s state, exit code, and history depends on knowing what docker ps reports and how docker run recorded the container.


a. docker run: creating and starting a container

docker run creates a container from an image and starts it. If the image is not present locally, Docker pulls it from the registry first.

docker run nginx

This starts an nginx container in the foreground. The terminal is attached, and Ctrl+C stops the container. The container is created with a random name and ID.

The most common flags control the mode, naming, networking, and persistence.

Detached mode (-d) runs the container in the background:

docker run -d nginx

The command returns immediately with the container ID. The container continues running until stopped.

Interactive mode (-it) attaches an interactive terminal:

docker run -it ubuntu /bin/bash

The -i keeps stdin open, and -t allocates a pseudo-TTY. This is used for shells and interactive processes.

Naming (--name) assigns a human-readable name:

docker run -d --name web nginx

The name must be unique. If omitted, Docker generates a random name. The name can be used in place of the container ID in other commands.

Port mapping (-p) publishes a container port to the host:

docker run -d -p 8080:80 nginx

The format is host_port:container_port. The container’s port 80 is accessible on the host’s port 8080.

Volume mounting (-v or --mount) persists data or shares files with the host. The --mount flag is the modern, more explicit syntax .

docker run -d -v mydata:/var/lib/mysql mysql

This mounts the named volume mydata at /var/lib/mysql. Named volumes persist independently of the container. Bind mounts use a host path instead of a volume name:

docker run -d -v $(pwd)/html:/usr/share/nginx/html nginx

Environment variables (-e) set variables inside the container:

docker run -d -e MYSQL_ROOT_PASSWORD=secret mysql

Automatic cleanup (--rm) removes the container when it stops:

docker run --rm -it ubuntu /bin/bash

This is useful for temporary containers that should not accumulate.

Resource limits constrain the container’s resource usage. The --memory and --cpus flags are the most common :

docker run -d --memory=512m --cpus=1.5 nginx

The exit code of docker run indicates whether the container started successfully. Exit codes 125, 126, and 127 indicate Docker daemon errors, command invocation errors, and command-not-found errors respectively. Other exit codes are the exit code of the container’s process .


b. docker ps: listing containers

docker ps lists running containers. Without flags, it shows only containers that are currently running.

docker ps

The output includes the container ID, image, command, creation time, status, ports, and name. The status column shows Up with the elapsed time for running containers.

All containers (-a or --all) shows stopped containers as well as running ones :

docker ps -a

The status column shows Exited with the exit code and elapsed time since exit. This is how you find stopped containers that can be restarted or removed.

Quiet mode (-q) shows only container IDs:

docker ps -q

This is useful for scripting. docker ps -aq returns all container IDs, which can be piped to other commands for batch operations.

Latest container (-l) shows the most recently created container, including stopped ones:

docker ps -l

Last n containers (-n) shows the n most recently created containers:

docker ps -n 5

Filtering (-f or --filter) narrows the list by conditions. Common filters include status, ancestor, name, and volume .

docker ps --filter status=exited
docker ps --filter ancestor=nginx
docker ps --filter name=web

Formatting (--format) customizes the output using Go templates :

docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Status}}"

Common placeholders include .ID, .Names, .Image, .Status, .Ports, and .State.


c. docker stop: stopping a running container

docker stop sends a termination signal to the container’s main process and waits for it to exit gracefully.

docker stop web

The default signal is SIGTERM, which asks the process to shut down cleanly. After a grace period (default 10 seconds), if the process has not exited, Docker sends SIGKILL, which forcibly terminates it .

Custom signal (-s or --signal) changes the signal sent:

docker stop -s SIGINT web

Timeout (-t or --timeout) changes the grace period:

docker stop -t 30 web

This waits 30 seconds before sending SIGKILL. A timeout of 0 sends SIGKILL immediately after SIGTERM.

Multiple containers can be stopped in one command:

docker stop web db cache

A stopped container retains its filesystem and configuration. It can be restarted with docker start and retains any data written to its writable layer, though that layer is ephemeral and will be lost if the container is removed.


d. docker rm: removing a container

docker rm removes a container. The container must be stopped first; attempting to remove a running container fails unless forced.

docker rm web

The command returns the name of the removed container.

Force removal (-f or --force) removes a running container by sending SIGKILL first :

docker rm -f web

This is useful for cleanup but bypasses the graceful shutdown that docker stop provides. The container’s process receives SIGKILL immediately, which may leave data in an inconsistent state.

Volume removal (-v or --volumes) removes anonymous volumes associated with the container :

docker rm -v web

Named volumes are not removed by this flag; they must be removed separately with docker volume rm. Anonymous volumes are those created implicitly by the container without a name.

Multiple containers can be removed in one command:

docker rm web db cache

Batch cleanup. To remove all stopped containers, combine docker ps with docker rm :

docker rm $(docker ps -a -q)

Or use the built-in prune command:

docker container prune

The prune command removes all stopped containers and reports the reclaimed space. It is safer than the shell expansion because it does not depend on shell features and handles edge cases like container names with spaces.


Complete Example Session

# ============================================
# PART 1: RUN A DETACHED CONTAINER
# ============================================
# Start nginx in the background with a name and port mapping.

docker run -d --name web -p 8080:80 nginx
# ============================================
# PART 2: LIST RUNNING CONTAINERS
# ============================================
# Show the running container.

docker ps
# ============================================
# PART 3: LIST ALL CONTAINERS
# ============================================
# Show running and stopped containers.

docker ps -a
# ============================================
# PART 4: RUN AN INTERACTIVE CONTAINER
# ============================================
# Start an Ubuntu shell with automatic cleanup.

docker run --rm -it ubuntu /bin/bash
# ============================================
# PART 5: STOP THE CONTAINER
# ============================================
# Gracefully stop the nginx container.

docker stop web
# ============================================
# PART 6: VERIFY THE CONTAINER IS STOPPED
# ============================================
# The container should show Exited status.

docker ps -a
# ============================================
# PART 7: RESTART THE CONTAINER
# ============================================
# Start the stopped container again.

docker start web
docker ps
# ============================================
# PART 8: FORCE REMOVE A RUNNING CONTAINER
# ============================================
# Remove the running container immediately.

docker rm -f web
# ============================================
# PART 9: REMOVE ALL STOPPED CONTAINERS
# ============================================
# Clean up with prune.

docker container prune
# ============================================
# PART 10: BATCH REMOVE WITH PS AND RM
# ============================================
# Alternative cleanup using shell expansion.

docker rm $(docker ps -a -q)

These ten parts cover the full lifecycle: running a container in detached and interactive modes, listing running and all containers, stopping, restarting, removing, and batch cleanup.


Quick Reference

Command Summary

CommandPurposeExample
docker runCreate and start a containerdocker run -d nginx
docker psList containersdocker ps -a
docker stopStop a running containerdocker stop web
docker rmRemove a containerdocker rm web

docker run Flags

FlagPurpose
-dDetached (background)
-itInteractive terminal
--nameAssign a name
-p host:containerPublish ports
-v source:targetMount volume or bind
--mountExplicit mount syntax
-e KEY=valueSet environment variable
--rmRemove on exit
--memoryMemory limit
--cpusCPU limit

docker ps Flags

FlagPurpose
-aShow all containers
-qOnly IDs
-lLatest container
-n NLast N containers
-fFilter output
--formatCustom template

docker stop and rm Flags

CommandFlagPurpose
docker stop-sCustom signal
docker stop-tTimeout before SIGKILL
docker rm-fForce remove running
docker rm-vRemove anonymous volumes

Best Practices

✅ Do This:

docker run -d --name web -p 8080:80 nginx        # Named, detached, port-mapped
docker run --rm -it ubuntu /bin/bash              # Interactive with cleanup
docker ps -a                                      # Check all containers
docker stop web && docker rm web                  # Graceful stop then remove
docker container prune                            # Batch cleanup

❌ Don’t Do This:

docker run nginx                                  # ❌ Foreground; blocks terminal
docker rm -f web                                  # ❌ Force without trying graceful stop
docker rm $(docker ps -a -q)                      # ❌ Removes running containers too
docker run --rm -d nginx                          # ❌ Contradictory: --rm removes on exit
docker ps                                         # ❌ Misses stopped containers

Common Pitfalls

PitfallWhy It HappensFix
Cannot remove containerContainer is still runningdocker stop first or use -f
Container exits immediatelyNo long-running processUse a foreground command
Data lost after removalData in writable layerUse volumes for persistence
Port already in useAnother process on host portChange host port mapping
Name already in useContainer with same name existsRemove old container or use different name
docker ps shows nothingOnly running containers shown by defaultUse docker ps -a
Cleanup removes running containersUsing docker rm $(docker ps -a -q)Filter by status=exited

Real-World Examples

1. Web Server

docker run -d --name web -p 80:80 nginx

2. Database with Volume

docker run -d --name db -v pgdata:/var/lib/postgresql/data -e POSTGRES_PASSWORD=secret postgres

3. Interactive Debugging

docker run --rm -it alpine sh

4. Resource-Limited Service

docker run -d --memory=512m --cpus=1.0 redis

5. List Containers by Status

docker ps --filter status=running
docker ps --filter status=exited

6. Format Container List

docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"

7. Graceful Stop with Timeout

docker stop -t 30 web

8. Remove Container with Volumes

docker rm -v web

9. Clean All Stopped

docker container prune

10. Remove Specific Containers

docker rm web db cache

Visual

Container Lifecycle

┌──────────────────────────────────────────────────────────────┐
│  CONTAINER LIFECYCLE                                         │
│                                                              │
│  ┌─────────────┐                                             │
│  │   IMAGE     │                                             │
│  └──────┬──────┘                                             │
│         │ docker run                                         │
│         ▼                                                    │
│  ┌─────────────┐                                             │
│  │  CREATED    │                                             │
│  └──────┬──────┘                                             │
│         │ start                                              │
│         ▼                                                    │
│  ┌─────────────┐    docker stop    ┌─────────────┐          │
│  │  RUNNING    │ ─────────────────▶│  STOPPED    │          │
│  │             │◀───────────────── │             │          │
│  └──────┬──────┘    docker start   └──────┬──────┘          │
│         │                                  │                 │
│         │ docker rm -f                     │ docker rm       │
│         ▼                                  ▼                 │
│  ┌────────────────────────────────────────────────────────┐  │
│  │                    REMOVED                             │  │
│  └────────────────────────────────────────────────────────┘  │
│                                                              │
│  docker ps shows RUNNING; docker ps -a shows all states.     │
└──────────────────────────────────────────────────────────────┘

docker run Flag Composition

┌──────────────────────────────────────────────────────────────┐
│  docker run -d --name web -p 8080:80 -v data:/app nginx      │
│  │       │  │        │         │          │                  │
│  │       │  │        │         │          └── Image          │
│  │       │  │        │         └── Volume mount              │
│  │       │  │        └── Port mapping                        │
│  │       │  └── Name                                         │
│  │       └── Detached mode                                   │
│  └── Create and start                                        │
│                                                              │
│  Without -d: foreground, terminal attached                   │
│  With -d: background, returns container ID                   │
└──────────────────────────────────────────────────────────────┘

docker ps Output States

┌──────────────────────────────────────────────────────────────┐
│  STATUS COLUMN MEANINGS                                      │
│                                                              │
│  Up 5 minutes              → running, healthy                │
│  Up 5 minutes (unhealthy)  → running, health check failed    │
│  Exited (0) 2 hours ago    → stopped cleanly                 │
│  Exited (1) 2 hours ago    → stopped with error              │
│  Created                   → never started                   │
│  Paused                    → temporarily suspended           │
│  Dead                      → defunct, only removable         │
└──────────────────────────────────────────────────────────────┘

Stop vs Remove

┌──────────────────────────────────────────────────────────────┐
│  docker stop web          docker rm web                      │
│                                                              │
│  ┌─────────────┐          ┌─────────────┐                    │
│  │  Container  │          │  Container  │                    │
│  │  PRESERVED  │          │  DESTROYED  │                    │
│  └─────────────┘          └─────────────┘                    │
│                                                              │
│  Data: writable layer     Data: writable layer lost          │
│  kept                     Named volumes persist              │
│  Can restart with         Cannot restart; must run again     │
│  docker start                                                │
│                                                              │
│  Use stop for pause.     Use rm for cleanup.                 │
└──────────────────────────────────────────────────────────────┘

Summary

ItemValue
docker runCreate and start a container
docker psList running containers
docker ps -aList all containers
docker stopSend SIGTERM, then SIGKILL after timeout
docker rmRemove a stopped container
docker rm -fForce remove a running container
docker run -dDetached (background) mode
docker run -itInteractive terminal
docker run --rmRemove container on exit
docker container pruneRemove all stopped containers
Container IDLong UUID, short UUID, or name
Exit codes 125–127Docker daemon, command invocation, command not found

Key takeaways:

  • docker run creates and starts a container. Flags control mode (-d, -it), naming, networking, volumes, and resource limits. The image is pulled if not present locally.
  • docker ps shows running containers by default. Use -a to include stopped containers. The status column shows the container’s state and exit code.
  • docker stop sends SIGTERM and waits. After a grace period (default 10 seconds), it sends SIGKILL. The container is preserved and can be restarted.
  • docker rm removes a container. It fails on a running container unless -f is used, which sends SIGKILL first. Removed containers and their writable layers are gone.
  • Stopping and removing are different operations. docker stop preserves the container for restart; docker rm destroys it. Use stop for pause, rm for cleanup.
  • Volumes persist data beyond container removal. Named volumes survive docker rm unless explicitly removed with -v (for anonymous volumes) or docker volume rm.
  • Batch cleanup uses docker container prune or docker rm $(docker ps -a -q). The prune command is safer and handles edge cases better.

Remember: The four core Docker commands map to the four fundamental container operations: create, list, stop, and remove. docker run is the most complex because it accepts configuration for networking, storage, resources, and mode. docker ps is the window into container state, showing what is running and what has stopped. docker stop and docker rm are the cleanup commands, and the distinction between them is the distinction between pause and destroy. A stopped container retains its filesystem and can be restarted; a removed container is gone. Volumes are the mechanism for data that must survive removal. When you work with Docker daily, these four commands are the ones you use most often, and understanding their flags and interactions prevents the common frustrations of orphaned containers, lost data, and containers that cannot be cleaned up.



Stop using slow, ad-bloated tool sites! 🤮

🔎 Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)

⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free

🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!