What WATCHTOWER_CLEANUP Does
When WATCHTOWER_CLEANUP=true, Watchtower deletes the old image immediately after a container has been successfully recreated with the new one. It only removes images that Watchtower itself replaced — it never touches images belonging to other containers or ones you pulled manually.
services:
watchtower:
image: nickfedor/watchtower:latest
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WATCHTOWER_CLEANUP=true
- WATCHTOWER_POLL_INTERVAL=86400
restart: unless-stopped
Why Is It Off by Default?
Keeping the old image is a rollback safety net: if the new image is broken, you can instantly revert with docker compose up -d pinned to the previous tag. Enabling cleanup trades that safety net for disk space. For most homelabs, the trade is worth it — broken images are rare, full disks are not.
What Cleanup Keeps (and Removes)
| Item | Removed? |
|---|---|
| Image replaced by Watchtower | ✅ Yes |
| Images of containers Watchtower doesn't manage | ❌ No |
| Manually pulled images | ❌ No |
| Dangling layers from builds | ❌ No — use docker image prune |
| Anonymous volumes | ❌ No — needs WATCHTOWER_REMOVE_VOLUMES=true |
Reclaiming Disk Beyond Cleanup
Cleanup handles replaced images, but registries also leave dangling layers. Add a monthly prune (careful on shared hosts):
# Preview what would be removed first
docker image prune -a --filter "until=720h"
# Actually remove unused images older than 30 days
docker image prune -a --filter "until=720h" -f
Check disk usage anytime with docker system df.
What About Volumes?
Cleanup never touches volumes. If replaced containers accumulate anonymous volumes, set WATCHTOWER_REMOVE_VOLUMES=true — but be careful: this only makes sense when your data lives in named volumes or bind mounts, never in anonymous ones.