Compose profiles and override files

Docker · lesson 24 of 31 · 3 min read

Keep one compose file for the whole team and switch optional services on per environment.

Open this lesson in the learning hub

Key points

  • A service with a profiles: key is skipped by a plain docker compose up until you ask for that profile.
  • Use it for the extras - an admin UI, a seed job, a mail catcher - so the core stack stays fast for everyone else.
  • compose.override.yaml is merged on top of compose.yaml automatically. Keep dev-only mounts and ports there.
  • For other environments be explicit: docker compose -f compose.yaml -f compose.prod.yaml up -d merges in that order.
  • docker compose config prints the final merged file. Run it before anyone argues about what is actually set.
  • docker compose watch syncs changed source into the running container, which beats rebuilding on every save.

Example

services:
  db:
    image: postgres:16
    environment: { POSTGRES_PASSWORD: secret }

  api:
    build: .
    ports: ["8080:8080"]
    depends_on: { db: { condition: service_healthy } }

  adminer:            # opt-in only
    image: adminer
    profiles: ["tools"]
    ports: ["8081:8080"]

# docker compose up -d                 -> db + api
# docker compose --profile tools up -d -> db + api + adminer
# docker compose -f compose.yaml -f compose.prod.yaml config

One compose file, profiles for the extras, config to settle the argument.

This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Docker course, and every lesson in it is listed on the Docker contents page.