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
| Command | Purpose | Example |
|---|---|---|
docker run | Create and start a container | docker run -d nginx |
docker ps | List containers | docker ps -a |
docker stop | Stop a running container | docker stop web |
docker rm | Remove a container | docker rm web |
docker run Flags
| Flag | Purpose |
|---|---|
-d | Detached (background) |
-it | Interactive terminal |
--name | Assign a name |
-p host:container | Publish ports |
-v source:target | Mount volume or bind |
--mount | Explicit mount syntax |
-e KEY=value | Set environment variable |
--rm | Remove on exit |
--memory | Memory limit |
--cpus | CPU limit |
docker ps Flags
| Flag | Purpose |
|---|---|
-a | Show all containers |
-q | Only IDs |
-l | Latest container |
-n N | Last N containers |
-f | Filter output |
--format | Custom template |
docker stop and rm Flags
| Command | Flag | Purpose |
|---|---|---|
docker stop | -s | Custom signal |
docker stop | -t | Timeout before SIGKILL |
docker rm | -f | Force remove running |
docker rm | -v | Remove 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
| Pitfall | Why It Happens | Fix |
|---|---|---|
| Cannot remove container | Container is still running | docker stop first or use -f |
| Container exits immediately | No long-running process | Use a foreground command |
| Data lost after removal | Data in writable layer | Use volumes for persistence |
| Port already in use | Another process on host port | Change host port mapping |
| Name already in use | Container with same name exists | Remove old container or use different name |
docker ps shows nothing | Only running containers shown by default | Use docker ps -a |
| Cleanup removes running containers | Using 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
| Item | Value |
|---|---|
docker run | Create and start a container |
docker ps | List running containers |
docker ps -a | List all containers |
docker stop | Send SIGTERM, then SIGKILL after timeout |
docker rm | Remove a stopped container |
docker rm -f | Force remove a running container |
docker run -d | Detached (background) mode |
docker run -it | Interactive terminal |
docker run --rm | Remove container on exit |
docker container prune | Remove all stopped containers |
| Container ID | Long UUID, short UUID, or name |
| Exit codes 125–127 | Docker daemon, command invocation, command not found |
Key takeaways:
docker runcreates and starts a container. Flags control mode (-d,-it), naming, networking, volumes, and resource limits. The image is pulled if not present locally.docker psshows running containers by default. Use-ato include stopped containers. The status column shows the container’s state and exit code.docker stopsends SIGTERM and waits. After a grace period (default 10 seconds), it sends SIGKILL. The container is preserved and can be restarted.docker rmremoves a container. It fails on a running container unless-fis used, which sends SIGKILL first. Removed containers and their writable layers are gone.- Stopping and removing are different operations.
docker stoppreserves the container for restart;docker rmdestroys it. Use stop for pause, rm for cleanup. - Volumes persist data beyond container removal. Named volumes survive
docker rmunless explicitly removed with-v(for anonymous volumes) ordocker volume rm. - Batch cleanup uses
docker container pruneordocker 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!