Images and build cache consume disk. Inspect RAM separately: Linux buff/cache is filesystem cache that can be reclaimed when needed. A single snapshot cannot establish a memory leak.
Run these commands on the machine being cleaned. Mac and VPS Docker data are separate. Wait for CI builds, deployments and other environment operations to finish before cleanup.
1. Identify usage
df -h /
free -h
docker system df
docker buildx du
docker ps -a
docker stats --no-stream
df reports disk; free reports RAM and available memory; Docker system df reports images, volumes and build cache; Docker stats reports containers. macOS normally has no free command. Image sizes include shared layers, so summing all image sizes overstates uniquely occupied space.
2. Limit build cache
Build cache speeds later builds; it is not your database or uploaded files. On Docker Buildx versions supporting the flag, keep up to 2 GB:
docker buildx prune --all --max-used-space 2gb
Confirm Docker's prompt. Check available options with docker buildx prune --help. Another choice removes entries not used recently:
docker buildx prune --filter 'until=24h'
This affects the selected builder. Cleanup does not change deployment behavior, but future builds may download dependencies or compile again. Reclaimable is an estimate, not a guaranteed increase in free space, because layers may be shared.
3. Preserve release references before deleting images
Set the runtime root from your profile:
RUNTIME_ROOT=/srv/admingen/PROJECT_NAME/ENV_NAME
jq '{id, backend, admin, ops, services, imageArchive}' "$RUNTIME_ROOT/state/current.json" "$RUNTIME_ROOT/state/previous.json"
docker image ls
docker ps -a
PROJECT_NAME and ENV_NAME are path placeholders. If previous does not exist, inspect current only. Preserve current/previous application images, required service images across environments and anything needed by an unfinished operation.
An image named none or marked dangling is not necessarily disposable: a container or recorded release can reference its immutable ID without a tag. Broad image/system prune does not understand your release JSON and may remove rollback images.
Delete a specifically identified unused image without force:
docker image rm OLD_UNUSED_IMAGE_ID
4. Archives and CI candidates
Source/Archive also write ordinary tar files outside Docker. Build-cache prune does not remove them. Source CI keeps candidates under RUNTIME_ROOT/ci-source/candidates/PIPELINE_ID-JOB_ID/ and copies archives into RUNTIME_ROOT/image-archives/. Failed operations may retain incoming/staging files or the worktree path printed in their log.
du -h -d 2 "$RUNTIME_ROOT/ci-source" "$RUNTIME_ROOT/image-archives"
du -h -d 2 "$RUNTIME_ROOT/incoming" "$RUNTIME_ROOT/staging"
These are Linux commands. Match archive files against imageArchive.file and imageArchive.sha256 in current/previous; runtime copies normally use SHA256.tar names. Keep current/previous releases and unfinished-operation archives. Remove only selected obsolete files, never the complete runtime root. Automatic release-storage cleanup is not currently implemented.
5. Volumes and persistent data
docker volume ls
docker inspect POSTGRES_CONTAINER --format '{{json .Mounts}}'
Replace POSTGRES_CONTAINER with its actual name from docker ps. No named volumes does not mean there is no database: server PostgreSQL may use a bind mount such as RUNTIME_ROOT/data/postgres. Database, media/files, backup, secrets, pki and state directories are not cache.
Use sudo du -xhd1 / to find other large directories, then inspect those directories. Do not manually clean /var/lib/docker or /var/lib/containerd. For deleted files still held open, use sudo lsof +L1.
After cleanup, repeat df -h / and docker system df. Image roles · Backups.