Skip to main content

Що таке Docker Compose profiles і як їх використовувати?

Docker Compose profiles це спосіб mark'нути сервіси як opt-in. За замовчуванням сервіс у compose.yaml стартує, коли ти запускаєш docker compose up. Додавання profiles: ["name"] до сервісу перевертає це: сервіс лишається dormant, поки явно не активуєш цей profile. Це дозволяє тримати один Compose-file, що покриває «dev stack», «dev stack + debug-tool», «dev stack + load-test» тощо, без жонглювання кількома файлами.

Теорія

TL;DR

  • Сервіс без profiles завжди активний.
  • Сервіс з profiles: ["x"] активний лише якщо profile x enabled.
  • Активуй через CLI: docker compose --profile x up.
  • Або через env: COMPOSE_PROFILES=x docker compose up.
  • Кілька profile можуть бути активні одночасно (--profile x --profile y).
  • Сервіс може належати кільком profile (будь-який матч активує).
  • Dependency (depends_on) profiled-сервісу мають бути у profile або always-on; інакше startup fail.

Чому profile

Реальні Compose-стеки накопичують опційні штуки:

  • DB admin-UI (pgadmin, mongo-express, redis-commander)
  • Mail-catcher (mailhog, mailpit) для dev
  • Load-testing (k6, locust)
  • Tracing/metrics (Jaeger, Prometheus, Grafana), які крутиш лише, коли investigation
  • Tool-only profile: one-shot migrate-сервіс, що крутить DB-migration

Без profile, варіанти:

  1. Кілька файлів (compose.yaml, compose.debug.yaml), merged через -f. Працює, стає verbose.
  2. Comment-out-блоки. Sloppy, не version-friendly.
  3. Profiles: один файл, один source of truth, opt-in execution.

Правила активації

  • Compose збирає всі profile, активовані через --profile або COMPOSE_PROFILES (comma-separated).
  • Сервіс selected, якщо не має profiles: ключа АБО якщо будь-яке з profiles: значень матчить активований profile.
  • Решта сервісів ignored (не build'аться, не pull'аться, не стартують).
  • Targeting конкретного сервісу за іменем auto-активує його profile: docker compose up pgadmin працює навіть без --profile debug, якщо pgadmin у profile debug.

Приклади

Basic dev/debug split

yaml
# compose.yaml services: app: image: myorg/app:1.0 ports: ["3000:3000"] environment: DATABASE_URL: postgres://app:app@db:5432/app depends_on: - db db: image: postgres:16 environment: POSTGRES_USER: app POSTGRES_PASSWORD: app volumes: - dbdata:/var/lib/postgresql/data pgadmin: image: dpage/pgadmin4 profiles: ["debug"] environment: PGADMIN_DEFAULT_EMAIL: admin@local.test PGADMIN_DEFAULT_PASSWORD: admin ports: ["5050:80"] depends_on: - db volumes: dbdata:

Щоденний dev:

bash
docker compose up # стартує app + db. pgadmin dormant.

Коли треба pgadmin:

bash
docker compose --profile debug up # стартує app + db + pgadmin

One-shot tool: migration-runner

yaml
services: app: image: myorg/app:1.0 depends_on: db: condition: service_healthy db: image: postgres:16 healthcheck: test: ["CMD-SHELL", "pg_isready -U app"] migrate: image: myorg/app:1.0 profiles: ["tools"] command: ["npm", "run", "migrate"] depends_on: db: condition: service_healthy
bash
# Run migration один раз docker compose --profile tools run --rm migrate

migrate-сервіс лишається поза звичайним up. Запусти через --profile tools run --rm migrate, він крутиться раз, exit, gone.

Кілька profile per service

yaml
services: jaeger: image: jaegertracing/all-in-one profiles: ["tracing", "observability"] ports: ["16686:16686"]

Активується або --profile tracing, або --profile observability.

Комбінування profile

yaml
services: app: image: myorg/app:1.0 db: image: postgres:16 redis: image: redis:7 profiles: ["cache"] worker: image: myorg/app:1.0 command: ["npm", "run", "worker"] profiles: ["workers"] loadtest: image: locustio/locust profiles: ["perf"]
bash
# мінімально docker compose up # з cache + worker'ами docker compose --profile cache --profile workers up # perf-benchmark docker compose --profile cache --profile workers --profile perf up # через env (CI-friendly) COMPOSE_PROFILES=cache,workers docker compose up

Profile + depends_on

yaml
services: app: depends_on: ["db"] db: image: postgres:16 pgadmin: image: dpage/pgadmin4 profiles: ["debug"] depends_on: ["db"] # OK: db завжди active pgadmin-monitor: image: myorg/pgadmin-monitor profiles: ["debug"] depends_on: ["pgadmin"] # OK: pgadmin у тому ж profile

Якщо profiled-сервіс depends на іншому profiled-сервісі, що не активований, Compose error:

yaml
services: app: depends_on: ["redis"] # помилка: app завжди active, redis profiled redis: profiles: ["cache"]

Фікс: або always-активуй redis (прибери profile), або перенеси app у cache-profile теж.

CI-friendly: env-driven

yaml
# compose.yaml, той самий файл для dev і CI services: app: image: myorg/app:1.0 db: image: postgres:16 e2e: image: myorg/e2e-tests profiles: ["e2e"] depends_on: ["app"]
yaml
# .github/workflows/test.yml - run: docker compose up -d # app + db - run: COMPOSE_PROFILES=e2e docker compose run --rm e2e - run: docker compose down

Dev отримує швидкий docker compose up; CI активує e2e, щоб запустити test-suite.

Реальне застосування

  • Internal-tool inclusion: pgadmin, redis-commander, queue-monitor, opt-in.
  • Heavy add-on: ELK-стек для логів, Jaeger для трейс, вмикай, коли investigation.
  • One-shot run: migration, seed-data, cron-job, profiles: ["tools"], run через compose run --rm.
  • Multi-environment-config: dev, staging, e2e-profile, swap'ом, які сервіси беруть участь.
  • Опційні dependency: caching-layer, який можна disable у dev для швидкості.

Типові помилки

Забувати depends_on-обмеження

yaml
services: app: depends_on: ["queue"] queue: profiles: ["workers"]

docker compose up fail: app завжди active, але dependency немає. Або прибери profile з queue, або перенеси app у той самий profile.

Бери profile, коли override простіший

Для environment-specific-config (різні image-tag, різні env-var), compose.override.yaml або -f compose.staging.yaml більш idiomatic. Profiles найкращі для opting in optional service, не transforming того ж сервісу через environment.

Сюрприз активації profile

bash
docker compose up pgadmin # pgadmin's profile auto-активується. Інші dev-tool у тому ж profile теж стартують.

Якщо ти хочеш стартувати лише один profiled-сервіс, target його явно. Якщо інші у його profile приходять разом, це intentional (вони шарять profile).

Забути --profile на down

bash
docker compose --profile debug up # 4 сервіси running docker compose down # лише always-active 3 зупинено

down лише зупиняє те, що up стартував би з поточними profile. Матчи profile-флаги на обох кінцях, або бери docker compose down --remove-orphans, щоб поймати решту.

Питання для поглиблення

Q: Чи може сервіс бути в кількох profile?


A: Так. Активація будь-якого з них вмикає сервіс.

Q: Чи docker compose ps показує profiled-сервіси, що dormant?


A: Ні, лише сервіси, що частина поточного selection. Щоб побачити всі defined-сервіси, бери docker compose config --services.

Q: Чи може profile активувати інші profile?


A: Ні. Profile це flat-list. Якщо хочеш meta-profile, активуй кілька через env-var.

Q: Що відбувається з docker compose build і profile?


A: Ті самі правила selection. Без --profile, лише always-active-сервіси build'аться. З --profile name, matching profiled-сервіси теж build'аться.

Q: (Senior) Коли profile mало, і яка альтернатива?


A: Profile хороші для opt-in-сервісу. Бореться, коли треба різний config для того ж сервісу через environment (різні image-tag, replica, env-var). Тоді бери кілька Compose-файлів, merged через -f compose.yaml -f compose.prod.yaml. Кожен файл може override або extend попередній. Profile + override-файли не взаємовиключні; вирішують різні проблеми.

Q: (Senior) Як profile взаємодіють з docker compose watch?


A: watch лише моніторить сервіси, що частина active-selection. Якщо docker compose --profile debug watch, debug-only-сервіси теж watch'аться. Без profile, ignored. Тож profile дозволяють scope-watch до relevant subset.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Коментарі

Ще немає коментарів