Що таке 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"]активний лише якщо profilexenabled. - Активуй через 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, варіанти:
- Кілька файлів (
compose.yaml,compose.debug.yaml), merged через-f. Працює, стає verbose. - Comment-out-блоки. Sloppy, не version-friendly.
- 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у profiledebug.
Приклади
Basic dev/debug split
# 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:
docker compose up
# стартує app + db. pgadmin dormant.Коли треба pgadmin:
docker compose --profile debug up
# стартує app + db + pgadminOne-shot tool: migration-runner
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# Run migration один раз
docker compose --profile tools run --rm migratemigrate-сервіс лишається поза звичайним up. Запусти через --profile tools run --rm migrate, він крутиться раз, exit, gone.
Кілька profile per service
services:
jaeger:
image: jaegertracing/all-in-one
profiles: ["tracing", "observability"]
ports: ["16686:16686"]Активується або --profile tracing, або --profile observability.
Комбінування profile
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"]# мінімально
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 upProfile + depends_on
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:
services:
app:
depends_on: ["redis"] # помилка: app завжди active, redis profiled
redis:
profiles: ["cache"]Фікс: або always-активуй redis (прибери profile), або перенеси app у cache-profile теж.
CI-friendly: env-driven
# 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"]# .github/workflows/test.yml
- run: docker compose up -d # app + db
- run: COMPOSE_PROFILES=e2e docker compose run --rm e2e
- run: docker compose downDev отримує швидкий 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-обмеження
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
docker compose up pgadmin
# pgadmin's profile auto-активується. Інші dev-tool у тому ж profile теж стартують.Якщо ти хочеш стартувати лише один profiled-сервіс, target його явно. Якщо інші у його profile приходять разом, це intentional (вони шарять profile).
Забути --profile на down
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.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.
Коментарі
Ще немає коментарів