Skip to main content

This tool is ideal for maintaining a clean, performant, and clutter-free Docker ecosystem.

Project description

Docker Prune CLI

Docker Prune CLI

A flexible, safe, and automated CLI for cleaning unused Docker containers, images, volumes, and networks.

License Python PyPI version Docker Hub Docker Image Size GHCR Podman Rootless Read-Only FS

Profile: Conservative Profile: Default Profile: Act Profile: Aggressive

docker-prune is a powerful and flexible CLI tool for managing and cleaning up unused Docker resources — including containers, images, volumes, and networks. Unlike basic docker system prune, this tool allows you to define complex, fine‑grained cleanup rules via filters, labels, regex patterns, and YAML configuration files.

This makes it ideal for:

  • Homelab environments — keep your systems clean and healthy without manual intervention.
  • Production & CI/CD — automate safe cleanup policies to prevent disk bloat.
  • Developers — quickly reclaim space while keeping important resources intact.

With semantic versioned Docker images, built‑in cleanup profiles, and a cron‑based scheduler, docker-prune can run fully automated in the background, tailored to your needs — all inside a rootless container for improved security.


Features

  • Container Management: Stop and remove containers based on age, name, labels, and restart count.
  • Image Cleanup: Remove unused images with filters for age, tags, and labels.
  • Volume Pruning: Delete unused volumes with label-based filters and age-based rules.
  • Network Pruning: Remove unused Docker networks, excluding built-in networks (bridge, host, none) and custom exclusions.
  • Detailed Storage Info: View disk usage statistics for Docker images and volumes.
  • Configurable: Load cleanup configurations via YAML files.
  • Rootless by Default: The official Docker image runs as a non-root user (app) with configurable UID/GID for enhanced security.

Installation

To install the docker-prune binary, run:

pip install docker-prune

This will make the docker-prune command available in your system's PATH.


Using the Docker Image

In addition to installing via pip, you can run docker-prune directly from its published Docker image. Images are available from:

  • GitHub Container Registry (GHCR): ghcr.io/t4skforce/docker-prune
  • Docker Hub: t4skforce/docker-prune

Security: Runs as rootless app user by default (UID=1000, GID=967) for improved security.

Pull Image

docker pull ghcr.io/t4skforce/docker-prune:latest
docker pull t4skforce/docker-prune:latest

Version Tags

The images follow Semantic Versioning (SemVer) and multiple tags are published for each release:

Tag example Description
latest Always points to the latest stable release
v1.0.4 Full SemVer – pinned to an exact release
v1.0 Minor version – receives updates for all v1.0.x releases
v1 Major version – receives updates for all v1.x.x releases

This allows you to:

  • Track the latest release: use latest
  • Stay on a major release line: use v1
  • Stay on a specific minor line: use v1.0
  • Pin to an exact release: use v1.0.4

Examples:

# Always get latest v1.x.x release
docker pull ghcr.io/t4skforce/docker-prune:v1

# Pin to a specific version
docker pull t4skforce/docker-prune:v1.0.4

Running the Container

Run docker-prune from the container:

docker run --rm -it \
  -v /var/run/docker.sock:/var/run/docker.sock \
  ghcr.io/t4skforce/docker-prune:latest --help

Run with a specific profile and schedule:

docker run -d \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e DOCKER_PRUNE_PROFILE=aggressive \
  -e DOCKER_PRUNE_SCHEDULE="0 */6 * * *" \
  t4skforce/docker-prune:v1

Run with a custom configuration file:

docker run -d \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /path/to/config.yml:/config/config.yml \
  -e DOCKER_PRUNE_CONFIG_FILE=/config/config.yml \
  ghcr.io/t4skforce/docker-prune:v1.0.4

Using docker-compose for Scheduled Cleanup

You can also run docker-prune as a scheduled cleanup service using Docker Compose.
This is ideal for homelab or server environments where you want regular automated pruning without manual runs.

Example: daily cleanup at 3 AM using the default profile

version: "3.8"

services:
  docker-prune:
    image: ghcr.io/t4skforce/docker-prune:v1
    container_name: docker-prune
    restart: unless-stopped
    environment:
      # Choose one of: default, aggressive, conservative
      DOCKER_PRUNE_PROFILE: default
      
      # Optional: change the schedule (default is 0 2 * * *)
      DOCKER_PRUNE_SCHEDULE: "0 3 * * *"
      
      # Optional: set timezone
      TZ: Europe/Berlin
    volumes:
      # Mount Docker socket to control Docker on the host
      - /var/run/docker.sock:/var/run/docker.sock:ro
    read_only: true
    tmpfs:
      - /tmp:rw,noexec,nosuid,size=1024
      - /home/app/.docker:rw,noexec,nosuid,size=1024
    security_opt:
      - no-new-privileges:true
    network_mode: none

Example: aggressive cleanup every 6 hours

version: "3.8"

services:
  docker-prune:
    image: ghcr.io/t4skforce/docker-prune:v1
    restart: unless-stopped
    environment:
      DOCKER_PRUNE_PROFILE: aggressive
      DOCKER_PRUNE_SCHEDULE: "0 */6 * * *"
      TZ: UTC
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    read_only: true
    tmpfs:
      - /tmp:rw,noexec,nosuid,size=1024
      - /home/app/.docker:rw,noexec,nosuid,size=1024
    security_opt:
      - no-new-privileges:true
    network_mode: none

Deploy:

docker compose up -d

Check logs:

docker compose logs -f docker-prune

Usage

Get Info

docker-prune info

Displays storage usage information for Docker images and volumes.

Example Output:

INFO - Overall usage Images: 732.91MB Volumes: 1.31MB
INFO - Total reclaimed space: 0.00B

Run Cleanup Configurations

docker-prune run cleanup-config.yml

Runs cleanup commands from a YAML configuration file.

Additional options:

  • --validate: Validate the configuration file and exit without running any commands.
  • --exit / --no-exit: Exit immediately if a command exits with a non-zero status (default: --no-exit).

Manage Containers

The docker-prune containers command group lets you stop running containers or remove stopped containers using multiple filters.
All filters are combined with AND logic — only containers matching all specified filters are affected.

Notes:

  • The stop command affects running containers.
  • The rm command affects stopped containers only.
  • You can combine multiple filters to precisely target which containers to affect.
  • The --not-* filters are useful for protecting important containers from cleanup runs.

Stop Containers

docker-prune containers stop stops running containers that match your criteria.

Defaults:

  • --restart: 100 (stop containers restarted more than 100 times by default)
  • --not-label: Excludes containers with labels matching:
    • ^(com.docker|io.podman).keep=(1|true|yes)?$

Examples:

# Stop containers older than 1 week
docker-prune containers stop --age "1w"

# Stop containers with more than 50 restarts
docker-prune containers stop --restart 50

# Stop containers named like 'test-*' except those with 'keep' in the name
docker-prune containers stop --name "^test-.*" --not-name "keep"

Remove Containers

docker-prune containers rm removes stopped containers that match your criteria.

Supported filters:

  • --age / -a: Remove stopped containers older than the given age (default: 1w).
  • --name: Include only containers with names matching a regex.
  • --not-name: Exclude containers with names matching a regex.
  • --label: Include only containers with labels matching a regex.
  • --not-label: Exclude containers with labels matching a regex. Default exclusions:
    • ^(com.docker|io.podman).keep=(1|true|yes)?$

Examples:

# Remove stopped containers older than 2 weeks
docker-prune containers rm --age "2w"

# Remove stopped containers with label 'env=dev'
docker-prune containers rm --label "^env=dev$"

# Remove stopped containers with 'temp' in their name, except those with label 'keep=true'
docker-prune containers rm --name "temp" --not-label "^keep=true$"

Clean Docker Images

The docker-prune images command removes unused Docker images according to the filters you specify, and also performs additional automatic cleanup to reclaim disk space.

By default, it will:

  1. Remove images matching your filters, such as:

    • --age: Remove images older than the given age (default: 90d)
    • --tag / --not-tag: Include or exclude images by tag regex
    • --label / --not-label: Include or exclude images by label regex
  2. Prune dangling images (untagged images that are not used by any container).

  3. Prune the Docker build cache, optionally keeping a certain amount of build cache space using --keep-builds.

Examples:

Remove images older than 90 days (default):

docker-prune images --age "90d"

Remove images older than 30 days but exclude the latest tag:

docker-prune images --age "30d" --not-tag "^latest$"

Remove all unused images and keep only 500MB of build cache:

docker-prune images --keep-builds 500MB

Prune Volumes

The docker-prune volumes command removes unused Docker volumes based on filters you specify.
By default, it:

  1. Targets only dangling volumes (not referenced by any container).
  2. Applies your filters to decide which volumes to delete.
  3. Excludes common volumes used by Docker Compose and Podman unless you override the exclusions.
  4. After filtered deletion, also runs a volume prune to remove any remaining anonymous volumes.

Default --not-label exclusions:

  • ^(com.docker|io.podman).compose.(project|volume)
  • ^(com.docker|io.podman).keep=(1|true|yes)?$

Examples:

Remove dangling volumes older than 30 days (default):

docker-prune volumes

Remove dangling volumes older than 7 days:

docker-prune volumes --age "7d"

Remove volumes with names starting with temp_:

docker-prune volumes --name "^temp_"

Remove volumes except those matching important in the name:

docker-prune volumes --not-name "important"

Remove all unused volumes, ignoring default label exclusions:

docker-prune volumes --not-label ""

Delete Networks

The docker-prune networks command removes unused custom Docker networks based on filters you specify.

By default, it:

  1. Targets only custom networks that are not currently attached to any container.
  2. Applies your filters to decide which networks to delete.
  3. Excludes built-in networks (bridge, host, none) automatically.
  4. Excludes common Compose/Podman networks and networks explicitly marked to keep, unless you override the exclusions.

Examples:

Remove unused custom networks older than 15 days:

docker-prune networks --age "15d"

Remove unused networks with names starting with temp_:

docker-prune networks --name "^temp_"

Remove unused networks except those matching important in the name:

docker-prune networks --not-name "important"

Remove all unused networks, ignoring default label exclusions:

docker-prune networks --not-label ""

Note:

  • Built-in networks (bridge, host, none) are always excluded from pruning and cannot be included.
  • The default --not-label option excludes networks commonly associated with docker-compose or Podman projects, such as:
    • ^(com.docker|io.podman).compose.(project|network)
    • ^(com.docker|io.podman).keep=(1|true|yes)?$

Debug Mode

Enable detailed logging for debugging:

docker-prune --debug containers stop --age "2d"

YAML Configuration Example

You can specify cleanup rules in a YAML file:

- docker-prune containers stop --age "7d"
- docker-prune containers rm --age "30d"
- docker-prune images --age "90d" --not-tag "^latest$"
- docker-prune volumes --age "30d" --not-label "^com.docker.compose.project"
- docker-prune networks --age "15d"

Run the configuration:

docker-prune run config.yml

Profiles & Configuration

docker-prune comes with several built‑in cleanup profiles — pre‑defined YAML configuration files (config-*.yaml) baked into the container image.
These let you run cleanup tasks without writing your own config from scratch.

You can select a profile using the DOCKER_PRUNE_PROFILE environment variable, or override it entirely with a custom config via DOCKER_PRUNE_CONFIG_FILE.

Available Profiles

Profile Purpose
default Balanced cleanup — safe for most environments. (see. config-default.yml)
aggressive Faster and more frequent cleanup — best when disk space is critical. (see. config-aggressive.yml)
conservative Minimal cleanup — prioritizes safety, good for production. (see. config-conservative.yml)
act Optimized for self‑hosted GitHub Actions runners using nektos/act. Cleans up aggressively between CI jobs to free space, while keeping commonly reused CI images cached to minimize registry pulls and speed up builds. (see. config-act.yml)

Default Cronjob Scheduler

The Docker container for docker-prune starts a cronjob scheduler by default. The cleanup tasks are executed based on the selected profile (default, aggressive, conservative, act) and are scheduled to run at 0 2 * * * (every day at 2:00 AM). Profiles act as shorthand for built-in configuration files, but users can provide a fully custom configuration file if needed.


Environment Variables

DOCKER_PRUNE_PROFILE:

  • Selects one of the built-in profiles (default, aggressive, conservative, act).
  • Example:
    -e DOCKER_PRUNE_PROFILE=aggressive
    

DOCKER_PRUNE_CONFIG_FILE:

  • Specifies the path to a custom configuration file. If provided, it overrides the profile-based default file.
  • Example:
    -e DOCKER_PRUNE_CONFIG_FILE=/path/to/custom-config.yaml
    

DOCKER_PRUNE_SCHEDULE:

  • Defines a custom cron schedule for the cleanup tasks. Accepts values supported by the Supercronic project.
  • Example:
    -e DOCKER_PRUNE_SCHEDULE="*/10 * * * *"  # Runs every 10 minutes
    

Docker Connection

Since docker-prune uses the Python Docker SDK, you can configure how it connects to the Docker daemon using the standard environment variables supported by the SDK.

If not set, the SDK defaults to:

  • Unix socket: /var/run/docker.sock on Linux/macOS
  • Named pipe: //./pipe/docker_engine on Windows

You can override this behavior using:

Variable Description Example
DOCKER_HOST URL to the Docker host. Use unix:///var/run/docker.sock for local or tcp://host:port for remote. tcp://192.168.1.50:2376
DOCKER_TLS_VERIFY Set to 1 to enable TLS verification. 1
DOCKER_CERT_PATH Path to the directory containing TLS certificates (ca.pem, cert.pem, key.pem). Required if DOCKER_TLS_VERIFY=1. /home/app/.docker
DOCKER_CONFIG Path to the Docker CLI config directory (used for authentication, etc.). /home/app/.docker

Example – connect to a remote Docker host with TLS:

export DOCKER_HOST=tcp://192.168.1.50:2376
export DOCKER_TLS_VERIFY=1
export DOCKER_CERT_PATH=$HOME/.docker/certs
docker-prune info

Example – run container with remote Docker host:

docker run -it \
  -e DOCKER_HOST=tcp://192.168.1.50:2376 \
  -e DOCKER_TLS_VERIFY=1 \
  -e DOCKER_CERT_PATH=/certs \
  -v /path/to/certs:/certs:ro \
  ghcr.io/t4skforce/docker-prune:latest info

For more details, see the Docker SDK for Python documentation on environment variables.


Docker Example Command

Run the Docker container with a custom profile (`aggressive`) and schedule
docker run -it \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e DOCKER_PRUNE_PROFILE=aggressive \
  -e DOCKER_PRUNE_SCHEDULE="0 */6 * * *" \
  -e TZ=Europe/Berlin \
  docker-prune:latest
Run the Docker container with a fully custom configuration file
docker run -it \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e DOCKER_PRUNE_CONFIG_FILE=/path/to/custom-config.yaml \
  -e DOCKER_PRUNE_SCHEDULE="0 */6 * * *" \
  -e TZ=Europe/Berlin \
  docker-prune:latest

Supported Custom Schedule

The DOCKER_PRUNE_SCHEDULE environment variable uses cron-style expressions for scheduling cleanup tasks. Below are a few examples:

Schedule Description
0 2 * * * Every day at 2:00 AM (default).
*/10 * * * * Every 10 minutes.
0 */6 * * * Every 6 hours.
0 3 * * 1 Every Monday at 3:00 AM.
30 1 1 * * On the first day of every month at 1:30 AM.

For more advanced scheduling options, refer to the Supercronic documentation.


Default Parameter Values

Many commands come with default values for parameters. Below are some commonly used defaults:

  • Containers:

    • --age: 1w (1 week) for rm command
    • --timeout: 60 (60 seconds before forcing stop)
    • --restart: 100 (only for stop command)
    • --not-label: By default, both stop and rm exclude containers with labels:
      • ^(com.docker|io.podman).keep=(1|true|yes)?$
  • Images:

    • --age: 90d (90 days)
  • Volumes:

    • --age: 30d (30 days)
    • --not-label: Excludes common docker-compose and Podman volume labels, plus keep-labels:
      • ^(com.docker|io.podman).compose.(project|volume)
      • ^(com.docker|io.podman).keep=(1|true|yes)?$
  • Networks:

    • --age: None (manual configuration required)
    • --not-name: Excludes bridge, host, none.
    • --not-label: By default excludes common Docker Compose / Podman network labels and keep-labels.
      • ^(com.docker|io.podman).compose.(project|network)
      • ^(com.docker|io.podman).keep=(1|true|yes)?$

Development

Requirements

  • Python 3.10 or higher
  • Docker Python SDK
  • Click library
  • JSON Schema validation library
  • PyYAML for YAML parsing

Setup with Pipenv

Clone the repository:

git clone https://github.com/t4skforce/docker-prune.git
cd docker-prune

Install dependencies using pipenv:

pip install pipenv
pipenv install --dev

Activate the virtual environment:

pipenv shell

Run the tool locally:

python -m docker_prune.cli --help

Run Locally with Docker

You can build and run the tool using Docker for testing in an isolated environment.

Build the Docker Image

docker build -t docker-prune:latest -f docker/Dockerfile .

Run the Docker Container

docker run -it \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e TZ=Europe/Berlin \
  -e DOCKER_PRUNE_SCHEDULE='*/10 * * * *' \
  -e DOCKER_PRUNE_DEBUG=false \
  docker-prune:latest

Contributing

Contributions are welcome! Feel free to open issues or submit pull requests.


Reporting Issues

If you encounter any bugs or have feature requests, please open an issue on the GitHub repository.


License

This project is licensed under the MIT License. See the LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

docker_prune-1.0.5.tar.gz (17.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

docker_prune-1.0.5-py3-none-any.whl (19.7 kB view details)

Uploaded Python 3

File details

Details for the file docker_prune-1.0.5.tar.gz.

File metadata

  • Download URL: docker_prune-1.0.5.tar.gz
  • Upload date:
  • Size: 17.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.6

File hashes

Hashes for docker_prune-1.0.5.tar.gz
Algorithm Hash digest
SHA256 e73b757f5d22c00bff4a969f4935ae161bec8f36f0c64abe2108a6ba29bac1b8
MD5 bc84cc61ed9a1e43f70750e935ae66be
BLAKE2b-256 e7657d2fad90016810e1238a084732077eb18587e2458ab3304e2c4a7e7c88d5

See more details on using hashes here.

File details

Details for the file docker_prune-1.0.5-py3-none-any.whl.

File metadata

  • Download URL: docker_prune-1.0.5-py3-none-any.whl
  • Upload date:
  • Size: 19.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.6

File hashes

Hashes for docker_prune-1.0.5-py3-none-any.whl
Algorithm Hash digest
SHA256 032718d370248cf488457908fde597a0f735b05fe7c448f422994202c41961b5
MD5 05ef8b530665d1723ab091c2a2e7bb65
BLAKE2b-256 b1c496a40c109ae4d91571c0a8306844c8384cd5e4e34655bbdb1942c4113c72

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page