Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що таке Docker Compose profiles і як їх використовувати?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Profiles** дозволяють tag'нути сервіси як opt-in. Сервіс з `profiles:` стартує лише, коли його profile запитаний через `--profile` (або `COMPOSE_PROFILES`). ```yaml services: app: image: myorg/app:1.0 # без profile = завжди стартує pgadmin: image: dpage/pgadmin4 profiles: ["debug"] # лише з --profile debug loadtest: image: locustio/locust profiles: ["perf"] ``` ```bash docker compose up # лише app docker compose --profile debug up # app + pgadmin docker compose --profile debug --profile perf up # всі три ``` **Use case:** dev-tools (pgadmin, redis-commander), perf-test-стек, опційні add-on, які не хочеш running by default.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**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.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.