Most people know docker compose config as “the validate command”. It’s much more than that. The same command can list resources, output JSON, hash services for change detection, and pin image digests for reproducibility.

Listing resources

Ask Compose what’s actually in your project, after all overrides and interpolation:

# List all services
docker compose config --services

# List all volumes
docker compose config --volumes

# List all images used
docker compose config --images

# List all defined profiles
docker compose config --profiles

These are great in scripts when you need to loop over each service:

for svc in $(docker compose config --services); do
  echo "=== Logs for $svc ==="
  docker compose logs "$svc" | tail -20
done

Filtering to a specific service

Show only the resolved configuration for one service:

docker compose config web

Useful when your Compose file is large and you only care about one piece.

Output formats

By default the resolved configuration comes back as YAML. Switch to JSON for programmatic use:

# Default YAML
docker compose config

# JSON for jq and friends
docker compose config --format json

# Extract just the environment of a service
docker compose config --format json | jq '.services.web.environment'

Hashing for change detection

--hash gives you a reproducible hash of a service’s configuration. Perfect for CI caching or detecting whether a service needs to be rebuilt:

# Hash every service
docker compose config --hash='*'
# web: 8f4e2a1b...
# db:  3c7d9e5f...

# Hash specific services
docker compose config --hash=web,api

If the hash doesn’t change, the service configuration is identical and you can skip expensive operations like rebuilding.

Pinning image digests

--resolve-image-digests replaces image tags with their current digests:

# Input: compose.yml
services:
  web:
    image: nginx:latest
docker compose config --resolve-image-digests
# Output
services:
  web:
    image: nginx:latest@sha256:a1b2c3...

Great for generating a production-ready, reproducible version of your Compose file.

Raw vs resolved

By default, Compose interpolates all ${VAR} references. Sometimes you want to see the file before substitution:

# Resolved (default)
docker compose config

# Raw, no interpolation
docker compose config --no-interpolate

This helps debug which variables are being substituted vs left as-is.

Combining with other commands

Pipe the resolved config to other tools:

# Save a resolved copy for production
docker compose config --resolve-image-digests > compose.resolved.yml

# Validate environment without starting services
docker compose config > /dev/null && echo "Config OK"

# See the full rendered config with overrides applied
docker compose -f compose.yml -f compose.prod.yml config

Further reading