Maintenance

Site is under maintenance — quizzes are still available.

Go to quizzes

List, stop, and remove containers

Learn to list running/stopped containers, stop them gracefully, and remove them to keep your Docker environment clean. Includes practical commands, common flags, and troubleshooting.

Focus: list, stop, and remove containers

Sponsored

If you've been running Docker containers in your local environment for a while, a handful of active containers can quickly turn into dozens of orphaned, stopped, or unused ones. Without knowing how to list, stop, and remove containers efficiently, your disk fills up, port collisions happen, and docker ps becomes a wall of noise. These three operations — listing, stopping, and removing — form the backbone of container lifecycle management and keep your development environment fast, clean, and predictable.

The problem this lesson solves

Docker doesn't automatically clean up after itself. Every time you run docker run, you leave behind a stopped container in the "Exited" state unless you explicitly remove it with --rm. After a few days of experimentation, you may see this familiar output:

docker ps -a
CONTAINER ID   IMAGE               STATUS                     PORTS     NAMES
b3f23a...   nginx:latest          Exited (0) 2 days ago                webserver-old
c7d89e...   python:3.10-slim      Exited (137) 4 hours ago            py-app
f2a1c2...   postgres:14           Exited (0) 1 week ago               pg-test

That's wasted resources — disk space for the container's writable layer, and mental overhead when you need to find the one container that's actually running.

The root cause? Beginners often know docker run but don't learn the complementary commands. They restart their machine, lose track, or worse — accumulate hundreds of anonymous containers until Docker screams about insufficient disk space.

After this lesson, you'll be able to: - See exactly what containers exist (running and stopped) - Stop one or all running containers without guessing - Permanently remove containers you no longer need

Core concept / mental model

Think of a Docker container like a lightweight disposable laptop. When you create one (docker run), you power it on. When you're done, you should shut it down (docker stop), and then either recycle or throw it away (docker rm). If you just walk away, the laptop stays on (container keeps running) or sits in a powered-off state on your shelf (stopped but still consuming disk space).

Key definitions

  • Running container: Active process that uses CPU, memory, and possibly ports. Listed by docker ps without flags.
  • Stopped container: Exited process. Still consumes finite disk space (about 10–100 MB per container) and retains its filesystem state. Listed by docker ps -a.
  • Removed container: Deleted permanently. Cannot be restarted — you must recreate it from an image.

The three-command pipeline

List  →  Stop (if running)  →  Remove

Each command has a clear purpose: 1. docker ps — discover what's out there. 2. docker stop — gracefully terminate the main process (SIGTERM, then SIGKILL after timeout). 3. docker rm — delete the container metadata and writable layer from disk.

Pro tip: If you skip stop and run docker rm -f, Docker sends SIGKILL immediately. This can corrupt stateful apps (databases, file writers). Always prefer stop then rm for production-like containers.

How it works step by step

The practical flow is a three-step loop:

Step 1 — List all containers

# Running only
docker ps

# All containers (running + stopped)
docker ps -a

# Quiet mode — show only container IDs
docker ps -aq

The -a flag (or --all) is the most common way to see stopped containers. Without it, you only see active ones — this is why beginners often think "my container disappeared" when in reality it just stopped.

Step 2 — Stop a running container

docker stop <container-id-or-name>

Docker sends a SIGTERM signal to the main process (PID 1 inside the container). By default, it waits 10 seconds for graceful shutdown. If the application doesn't exit in time, Docker sends SIGKILL.

You can also use: - docker stop -t 30 my-container — wait 30 seconds before killing. - docker kill my-container — immediate force stop (no grace period).

Step 3 — Remove a stopped container

docker rm <container-id-or-name>

If the container is still running, docker rm fails with:

Error response from daemon: You cannot remove a running container ...

Combine stop and remove in one line for convenience:

docker stop my-container && docker rm my-container

Or skip the stop entirely with force-remove:

docker rm -f my-container

Hands-on walkthrough

Let's create, list, stop, and remove containers together.

Setup — create two test containers

Run these commands to generate some containers to work with:

# Run an Nginx container in the background
docker run -d --name demo-nginx -p 8080:80 nginx:alpine

# Run a quick echo container that exits immediately
docker run --name demo-echo alpine echo "Hello from Docker"

Now list everything:

docker ps
docker ps -a

Expected output: - docker ps shows demo-nginx running (STATUS: Up ...). - docker ps -a shows both demo-nginx (Up) and demo-echo (Exited (0) ...).

Stop the running container

docker stop demo-nginx

Verify it stopped:

docker ps -a | grep demo-nginx
# Output: CONTAINER ... Exited (0) ...

Both containers are now stopped.

Remove both containers

docker rm demo-nginx demo-echo

Check that they're gone:

docker ps -a | grep demo-
# No output — containers are removed

Clean up all stopped containers at once

For daily housekeeping, this one-liner is gold:

docker container prune

It prompts for confirmation. To skip the prompt:

docker container prune -f

Warning: prune removes all stopped containers. Use it only when you're sure you don't need them anymore.

Remove all containers (running and stopped)

This is a power-user trick — use with care.

# Stop all running containers
docker stop $(docker ps -q)

# Remove all containers (now all stopped)
docker rm $(docker ps -aq)

Or in one line:

docker rm -f $(docker ps -aq)

This sends SIGKILL to everything. Great for a fresh start, but avoid on systems with stateful databases.

Compare options / when to choose what

Scenario Command Why
Stop a single container gracefully docker stop <name> Sends SIGTERM; app can flush data
Stop immediately (force) docker kill <name> Sends SIGKILL; no cleanup chance
Remove a single stopped container docker rm <name> Removes only that one
Remove a running container (force) docker rm -f <name> Stops and removes in one command
Remove all stopped containers docker container prune Safest bulk cleanup
Remove all containers (running+stopped) docker rm -f $(docker ps -aq) Nuclear option — only for dev/test

When in doubt, prefer the safe dance: 1. docker ps -a 2. docker stop <specific containers> 3. docker rm <specific containers>

Troubleshooting & edge cases

"Cannot remove container: is running"

Cause: You tried docker rm on a running container. Fix: Either stop first (docker stop then docker rm) or use force (docker rm -f).

Container disappears after docker run

Cause: You used the --rm flag when running. Example: docker run --rm alpine echo hi Solution: The container is automatically removed on exit. This is intentional — use it when you don't need the container after it stops.

docker ps -a shows no output even though you just ran a container

Cause 1: You forgot the -a flag. Run docker ps -a (not docker ps). Cause 2: The container exited and was created with --rm. It's gone forever. Cause 3: The container was already removed with docker rm or prune.

What about containers that fail to stop?

Some containers ignore SIGTERM and stay alive. Try: - docker kill <name> — immediate SIGKILL. - Check if the container has custom PID 1 behavior (e.g., tini, s6).

For stubborn containers:

docker kill <name>   # if stop doesn't work
docker rm -f <name>  # if even kill seems stuck (rare)

Large number of containers make prune slow

docker container prune can take time if you have hundreds of containers with large writable layers. Consider removing them in batches:

docker rm $(docker ps -aq --filter "status=exited" --filter "status=created")

What you learned & what's next

You now know the core lifecycle commands: - List containers with docker ps (running) and docker ps -a (all) - Stop gracefully with docker stop or forcefully with docker kill - Remove with docker rm, docker rm -f, or docker container prune

You can confidently manage container clutter and keep your development environment lean.

What's next? In the next lesson, you'll learn how to inspect and view logs of running containers — essential for debugging why your app crashes after a container restart. You'll use docker logs, docker inspect, and docker exec to dive inside the container and see what's really happening.

Until then, practice the safe dance: list, stop, then remove. Your hard drive will thank you.

Practice recap

Run docker run -d --name test-practice nginx:alpine, then list your containers. Stop the container with docker stop test-practice, verify it stopped, then remove it with docker rm test-practice. Finally, run docker ps -a to confirm it's gone. Repeat this cycle three times until the commands feel automatic.

Common mistakes

  • Running docker rm on a running container and getting an error — always stop first, or use docker rm -f.
  • Forgetting the -a flag and thinking containers vanished — always use docker ps -a to see stopped containers.
  • Using docker container prune without noticing that it removes ALL stopped containers, including ones you may need later.
  • Assuming docker stop is instant — it waits 10 seconds by default; use docker kill for immediate termination.
  • Using docker rm -f on a database container — this causes data loss since it sends SIGKILL without a graceful shutdown.

Variations

  1. Use docker kill <name> instead of docker stop when you need immediate termination without grace period.
  2. Use docker rm -v <name> to also remove the container's anonymous volumes — useful for cleaning up database containers.
  3. Use docker container list as an alternative to docker ps — some CI scripts prefer the long-form command for clarity.

Real-world use cases

  • Cleaning up dev containers after a spike in experimentation — use docker container prune to reclaim disk space.
  • Hot-swapping a service in a multi-container app — stop the old container, then start the new one with the same port mapping.
  • CI/CD pipeline cleanup — in a runner, stop and remove all containers to ensure a clean state before each job.

Key takeaways

  • docker ps shows running containers; docker ps -a shows all (including stopped).
  • Always docker stop before docker rm for graceful shutdown — use docker rm -f only in emergencies.
  • docker container prune removes all stopped containers at once — use with caution.
  • Combine stop and remove with docker stop <name> && docker rm <name> for controlled cleanup.
  • The --rm flag on docker run automatically removes the container when it stops — ideal for short-lived tasks.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.