19.2.7.4 Rm Cleanup Workflow
A focused guide to Rm Cleanup Workflow, connecting core concepts with practical Docker and container operations.
A Docker cleanup workflow built around docker rm addresses the accumulation of stopped containers, orphaned anonymous volumes, and the disk space they consume over time. Without a cleanup routine, a busy Docker host — particularly one running CI/CD pipelines, development environments, or frequently deployed services — will accumulate hundreds of stopped containers that are no longer needed. This accumulation slows down operations, consumes inodes and disk space, and makes monitoring output noisy.
Understanding What Accumulates
Each time a container exits or is stopped, it remains on the host in a stopped state. The container retains its writable filesystem layer (a copy-on-write layer on top of the image), its metadata, and any anonymous volumes it created. Running containers do not accumulate this way, but every test run, CI job, temporary task, or redeployed service leaves behind a stopped container unless it was started with --rm.
Phase 1: Audit Before Cleaning
Before removing anything, survey what exists:
docker ps -a
This lists all containers regardless of state. Review the STATUS column for Exited, Created, or Dead entries and the CREATED column to understand how old they are.
To see disk usage by containers:
docker system df
This shows a summary of space used by images, containers, volumes, and build cache, with reclaimable amounts clearly separated.
docker system df -v
The -v flag gives per-container and per-volume breakdowns.
Phase 2: Remove Stopped Containers
The safest targeted approach is:
docker container prune
Docker lists what will be removed and asks for confirmation. The output includes the total disk space reclaimed.
To skip the confirmation (for scripts):
docker container prune --force
To only prune containers older than a certain threshold (useful for keeping recently stopped containers for debugging):
docker container prune --filter "until=24h"
This removes only containers that stopped more than 24 hours ago, leaving recently stopped ones available for inspection.
Phase 3: Remove Orphaned Anonymous Volumes
Anonymous volumes created by containers are not removed when the container is deleted unless you used docker rm -v. To find and remove orphaned volumes:
docker volume prune
This removes all volumes not currently referenced by any container (running or stopped). It asks for confirmation before proceeding.
docker volume prune --force
Named volumes are included in the prune unless they are still in use by a container. Check named volumes before pruning if any are expected to be reused:
docker volume ls
Phase 4: Remove Dangling Images
Stopped containers reference images, but after containers are removed, images that are no longer tagged and not referenced by any container become dangling. To remove them:
docker image prune
To remove all unused images (not just dangling ones — this includes tagged images not used by any container):
docker image prune --all
Use --all with care in development environments where you want to keep cached images to speed up future builds.
Full System Cleanup
For a complete cleanup of all unused resources — stopped containers, dangling images, unused networks, and build cache — in one command:
docker system prune
To also include unused volumes:
docker system prune --volumes
To skip all confirmation prompts:
docker system prune --force --volumes
docker system prune is the most aggressive option and is best reserved for ephemeral hosts (CI runners, local dev machines) where you are confident nothing should be preserved.
Inline Cleanup During Development
For development workflows where you frequently run throwaway containers, use --rm on docker run to prevent stopped containers from accumulating in the first place:
docker run --rm my_image some_command
The container is deleted automatically when it exits. This is the cleanest approach for tasks, scripts, and test runs where you do not need the container after it completes.
CI/CD Pipeline Cleanup Pattern
In CI pipelines, a common pattern is to clean before starting a new job to ensure a predictable state, or to clean after completing a job to avoid accumulation across runs:
Pre-job cleanup:
docker container prune --force
docker volume prune --force
Post-job cleanup with force to catch anything still running:
docker rm -f $(docker ps -aq) 2>/dev/null || true
docker volume prune --force
The 2>/dev/null || true construct suppresses errors when no containers exist and ensures the script does not fail on a clean host.
Scheduled Cleanup
On long-running hosts, a scheduled cron job can keep Docker tidy:
0 2 * * * docker container prune --force && docker volume prune --force && docker image prune --force
This runs at 2 AM daily, removing stopped containers, orphaned volumes, and dangling images without interaction.
Verifying Cleanup Results
After running the cleanup workflow, verify the results:
docker ps -a
Should return only running containers and any intentionally retained stopped containers.
docker system df
Should show reduced reclaimable space or zero for containers and volumes.
docker volume ls
Should show only named volumes that are actively in use or intentionally retained.
A consistent cleanup workflow prevents disk exhaustion, reduces noise in monitoring tools, and ensures that Docker operations remain fast and predictable across the lifecycle of the host.