Remove old stopped Docker containers
Select disposable containers deliberately, understand prune age filters, and preserve data before scheduling cleanup.
docker container prune removes stopped containers after confirmation. “Stopped” does not mean “unneeded”: a container may retain diagnostic evidence, an intended rollback setup, or files that exist only in its writable layer.
Start with a narrow scope
docker ps -a --filter status=exited
docker system df -v
Review container identities, labels, creation times, and the data you need to retain. For an individual candidate, docker diff NAME shows writable-layer changes and docker cp can copy selected files out. Those commands do not replace an application-consistent database backup.
After that review, the general cleanup command is:
docker container prune
It can remove all stopped containers, including ones outside a particular application. --force only suppresses the prompt; it does not make the selection safer.
Filter by age and an explicit cleanup label
docker container prune \
--filter label=cleanup=approved \
--filter until=24h
Both conditions apply. The age filter means created more than 24 hours ago, relative to the daemon's clock. It does not mean “has been stopped for 24 hours.” A month-old container stopped a minute ago can qualify. If retention depends on exit time, inspect State.FinishedAt and implement that distinct policy explicitly.
until is a prune filter; do not copy it into docker ps as though container listing supported the same filters. List candidates by status and label, then inspect timestamps when an exact pre-deletion inventory is required. Prune has no general dry-run mode, and selection can change while other jobs run.
For reviewed IDs, docker rm ID1 ID2 removes those stopped containers. Avoid -f for routine cleanup: it can kill a container that is running. A broad name substring is a weak ownership boundary compared with an agreed cleanup label.
Know what broader pruning removes
| Command | Scope |
|---|---|
docker container prune |
Stopped containers |
docker system prune |
Stopped containers, unused networks, dangling images, and unused build cache |
docker system prune -a |
Also includes images unused by any remaining container |
docker system prune -a --volumes |
Also prunes eligible unused anonymous volumes |
Do not assume the last command removes every named volume, or that an anonymous volume is disposable. Removing stopped containers can make their images and anonymous volumes eligible during the broader operation.
Without -v, docker rm retains volumes. With -v, it removes associated eligible anonymous volumes; named volumes are not removed by that flag. The container's own writable layer is deleted either way.
Automate only an established policy
A deliberately scoped user-crontab entry might be:
0 3 * * 0 /usr/bin/docker container prune --force --filter label=cleanup=approved --filter until=168h >> /var/log/docker-cleanup.log 2>&1
Verify the executable path, daemon context, Docker access, log permissions, timezone, and log rotation for that account. Only containers labeled for this policy should qualify. A label is an operational convention, not a security boundary against another daemon administrator.
After cleanup, compare docker system df with filesystem space and inode usage. Guance disk metrics can track the relevant mount point; they do not attribute every byte to one Docker object. Shared layers, logs, build cache, and Desktop virtual disks can explain why apparent reclaim differs from host free space.
A deleted writable layer is not recoverable through docker start. Retained volume data may support a new container, provided the application configuration and data remain compatible.
See container prune and system prune.
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan