Skip to main content

compose-outdated

Check your Docker Compose stack for image updates without pulling any images. Shows current vs latest versions and fetches changelogs from GitHub.

Features

  • Parses docker-compose.yml / compose.yaml with full include: recursion
  • Queries Docker Hub, GHCR, and lscr.io for available tags
  • Compares versions within the same tag channel (e.g. -alpine tags stay in their lane)
  • Fetches release notes from GitHub for each available update
  • Supports environment variable interpolation (${VAR:-default})
  • Concurrent registry checks for fast results
  • No images are pulled -- registry APIs only

Setup

Requires Python 3.12+ and uv.

# Clone and install
git clone <repo-url> && cd compose-outdated
uv sync

# Or install directly with uv/pipx
uv tool install .

This installs two equivalent commands: compose-outdated and cod.

Usage

# Check compose file in the current directory
cod

# Check a specific directory or file
cod /path/to/my-stack
cod /path/to/docker-compose.yml

# Skip changelog fetching (faster, table-only output)
cod --no-changelog

# Only check specific services
cod -s traefik -s redis

# Set a GitHub token for higher API rate limits (also reads GITHUB_TOKEN env var)
cod --github-token ghp_xxxxx

# Control concurrent registry requests (default: 5)
cod -n 10

# Show more changelog context per release (default: 8 lines, 0 = unlimited)
cod -l 20
cod -l 0

# Save the full report to a file (always untruncated)
cod -o report.txt

# Compact terminal output but full detail in the file
cod -l 3 -o report.txt

Options

Flag Short Description
--changelog / --no-changelog -c / -C Enable/disable GitHub changelog fetching (default: on)
--github-token TEXT GitHub API token for higher rate limits
--service TEXT -s Only check named service(s), can be repeated
--concurrency INT -n Max concurrent registry checks (default: 5)
--body-lines INT -l Max lines per changelog body in terminal (0 = unlimited, default: 8)
--output PATH -o Write full report to file (changelogs are never truncated in the file)

Exit codes

Code Meaning
0 All images are up to date
1 Error (compose file not found, parse failure, etc.)
2 Updates are available

This makes it easy to use in scripts or CI:

cod --no-changelog /path/to/stack || echo "Updates available!"

Supported registries

  • Docker Hub (docker.io) -- uses the Hub REST API, no auth required for public images
  • GitHub Container Registry (ghcr.io) -- uses OCI Distribution API with anonymous tokens
  • LinuxServer (lscr.io) -- proxied through GHCR
  • Any OCI-compliant registry should work via the Distribution spec fallback

How changelogs are resolved

The tool tries several strategies to find the GitHub source repo for each image:

  1. Built-in known mappings for popular images (traefik, postgres, redis, cloudflared, etc.)
  2. GHCR / lscr.io path inference (image path usually matches the GitHub repo)
  3. docker-library/official-images manifest lookup (for official library/ images)
  4. Docker Hub repository metadata (parses README for GitHub links)
  5. GitHub search as a last resort

Once a repo is found, GitHub Releases are fetched and filtered to versions between your current tag and the latest.

Compose file support

The tool handles real-world compose setups:

  • compose.yaml, compose.yml, docker-compose.yaml, docker-compose.yml
  • Recursive include: directives (nested includes are followed)
  • Environment variable interpolation: $VAR, ${VAR}, ${VAR:-default}
  • Digest-pinned images (image:tag@sha256:...) -- the tag is extracted for comparison
  • Images without explicit tags default to latest

Version comparison

Tags are compared within "channels" to avoid false positives:

  • 1.25.3-alpine is only compared against other *-alpine tags
  • v-prefixed and non-prefixed duplicates are deduplicated (v3.6.10 and 3.6.10 count as one)
  • Non-semver tags like latest, stable, or commit SHAs are skipped

Development

uv sync                                    # install deps
uv run pytest                              # run tests
uv run pytest --cov=compose_outdated       # run tests with coverage
uv run ruff check .                        # lint
uv run ruff format .                       # format

This project uses Conventional Commits. Prefix your commit messages with feat:, fix:, chore:, docs:, test:, ci:, refactor:, etc.

Releasing a new version

  1. Ensure you're on master with a clean working tree and CI passing.
  2. Run the version bump:
    uv run cz bump
    
    This will:
    • Determine the next version from commit messages since the last tag
    • Update version in pyproject.toml
    • Update CHANGELOG.md
    • Create a commit and git tag (e.g. v0.4.0)
  3. Review the changes:
    git log -1 --stat
    git diff HEAD~1 CHANGELOG.md
    
  4. Push the commit and tag:
    git push origin master --follow-tags
    
  5. The CI publish job triggers on the tag, builds the package, and publishes to PyPI via OIDC trusted publisher.

PyPI trusted publisher setup (one-time)

On pypi.org, under the project's "Publishing" settings, add a new "GitLab" trusted publisher:

  • GitLab instance URL: gitlab.com
  • Project path: <your-namespace>/compose-outdated
  • Environment: pypi
  • Top-level pipeline or workflow name: .gitlab-ci.yml

Metadata

Release files for compose-outdated 0.4.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for compose-outdated 0.4.1
File Size Uploaded Provenance Actions
compose_outdated-0.4.1.tar.gz 61.6 kB Without provenance Details for compose_outdated-0.4.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for compose-outdated 0.4.1
File Interpreter ABI Platform Actions
compose_outdated-0.4.1-py3-none-any.whl Python 3 none any Details for compose_outdated-0.4.1-py3-none-any.whl

Total release size: 79.4 kB

Release files / compose_outdated-0.4.1.tar.gz

Download URL compose_outdated-0.4.1.tar.gz
Size 61.6 kB
Tags Source
SHA-256 checksum
How to use checksums
de25e6ac1c1bb182085d298f87be7a8c0c8dedc9e0c5e83a042d0257fe463b89
BLAKE2b-256 checksum
How to use checksums
34cc17d9ab8c2c6177dbd9ced3c930aac1ecfc8f36a4b718dbffc3bca27c14e5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.9.30 {"installer":{"name":"uv","version":"0.9.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / compose_outdated-0.4.1-py3-none-any.whl

Download URL compose_outdated-0.4.1-py3-none-any.whl
Size 17.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
da0ea34f9ff1c70abeb52836feb4b020f0cfed8d4e0e5878df6bfbc899d7b394
BLAKE2b-256 checksum
How to use checksums
7725b0644b459a35eb3b33c16618033eef626e58c06b634f56a351621e9b82ce
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.9.30 {"installer":{"name":"uv","version":"0.9.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for compose-outdated 0.4.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.4.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page