✦ For everyone, free.

Practical knowledge for real and everyday life

Home

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.