Docker Compose удобно думать не как про «ещё одну команду Docker», а как про способ описать всё приложение целиком в одном файле и запускать его одним жестом. Вместо того чтобы руками поднимать веб, базу, кеш, брокер сообщений и связывать их между собой, вы складываете всё это в docker-compose.yml, а дальше просто поднимаете стек целиком. Особенно это ценится на VPS и любых серверных окружениях, где важно быстро развернуть одно и то же окружение хоть десять раз подряд.
Вместо серии docker run и возни с параметрами у вас появляется декларативное описание инфраструктуры. Дальше всё сводится к одной команде:
docker compose up -dОсновные элементы конфигурации Docker Compose #
Внутри docker-compose.yml обычно крутятся всё те же сущности, но уже в более удобном виде:
- services — описание самих сервисов: какой образ или Dockerfile использовать, какие порты открыть, какие переменные окружения нужны. Это могут быть веб-приложение, БД, кеш и т. д.;
- networks — как сервисы общаются по сети, какие из них видят друг друга, а какие изолированы;
- volumes — постоянное хранение данных вне контейнера, чтобы при перезапуске ничего не пропадало, например том для PostgreSQL или Redis;
- environment — переменные окружения с настройками: адреса БД, логины, токены;
- ports — правила проброса портов с хоста внутрь контейнеров, вроде 8080:8080 для доступа к веб-сервису;
- depends_on — зависимости между сервисами и порядок их запуска, чтобы приложение не стартовало раньше базы.
Пример конфигурации docker-compose.yml #
Ниже довольно типичный пример, когда у нас есть веб-приложение app и база PostgreSQL. Пример показывает базовые вещи: проброс порта, переменные окружения, зависимость от базы и отдельный том для данных.
version: "3.9"
services:
app:
build: .
ports:
- "8080:8080"
environment:
DB_HOST: db
DB_USER: appuser
depends_on:
- db
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: appuser
POSTGRES_PASSWORD: secret
POSTGRES_DB: appdb
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:Если разобрать этот файл по частям:
- app — веб-сервис, который собирается из Dockerfile в текущей директории (build: .);
- ports: "8080:8080" — наружу пробрасывается порт 8080, так что к приложению можно обратиться с хоста по этому порту;
- environment в блоке app — настройки подключения к базе (имя хоста, пользователь и т. д.);
- depends_on: db говорит Compose сначала поднимать БД, а потом уже приложение;
- db — сам PostgreSQL на официальном образе;
- volumes: db_data — именованный том, где лежат данные БД, переживает пересоздание контейнера;
- version: "3.9" — версия формата, в которой написан конфиг.
Преимущества инструмента #
Compose любят за то, что он сильно экономит время и убирает лишнюю магию. Что в нём особенно полезно:
- Быстрый запуск окружений. Всё приложение поднимается одной командой, без кучи скриптов;
- Воспроизводимость. Конфиг в Git — и у всех разработчиков и на всех серверах получается одинаковое окружение;
- Изоляция. Для dev, теста и продакшна легко держать разные конфиги или override-файлы;
- Гибкость. Хотите сменить образ, добавить том или порт — правите YAML, а не лезете в каждый контейнер;
- Прозрачность. Вся команда видит, из чего состоит инфраструктура, без «секретных настроек» в чьём-то локальном скрипте.
Как используется #
В реальных проектах Compose редко ограничивается одним-единственным файлом. Обычно это выглядит так:
Override-файлы вроде docker-compose.override.yml для разработки: монтируем исходники, включаем hot-reload, добавляем отладчики — всё это можно описать отдельно, не трогая базовый прод-конфиг.
- .env — вынос секретов и переменных окружения из YAML, чтобы не светить их в конфиге;
- Profiles — возможность запускать только нужные сервисы. Например, профиль отладки:
docker compose --profile debug up- Несколько файлов конфигурации — когда базовый конфиг дополняется прод- или тестовым:
docker compose -f docker-compose.yml -f docker-compose.prod.yml up- Multi-stage build вместе с Compose — позволяет собирать более компактные и безопасные образы без лишних dev-зависимостей.
Интеграция и масштабирование #
Compose легко встраивается в более широкую экосистему и нередко становится первым шагом к продакшн-инфраструктуре. Один и тот же docker-compose.yml может использоваться и локально, и в CI, и в кластере. Основные варианты:
- Docker Swarm. Тот же конфиг часто можно почти без изменений использовать для развертывания сервисов в кластере Swarm;
- CI/CD. В пайплайнах Compose запускает временное окружение для тестов и интеграции, а потом всё аккуратно гасится;
- Kubernetes. Через утилиту Kompose конфиг Compose конвертируют в манифесты Kubernetes и переносят приложение в кластер.
Типичные ошибки при работе с Docker Compose #
Несмотря на понятный синтаксис, с Compose тоже часто косячат. Пара типичных промахов:
- Секреты в конфиге. Логины, пароли и ключи в явном виде в docker-compose.yml — плохая идея. Для этого есть .env и Docker secrets;
- Тег latest. Привязка к «latest» без конкретной версии образа ведёт к тому, что однажды всё обновится само и что-нибудь перестанет работать;
- Без тома для БД. Если база крутится без volume, данные просто исчезнут при пересоздании контейнера;
- Один файл на все случаи. Пытаться одной конфигурацией закрыть и dev, и prod — почти гарантированный источник ошибок. Лучше разделять окружения или использовать override.
Безопасность и эксплуатация #
Когда Compose начинают использовать не только на локалке, но и в бою, к нему автоматически подтягиваются вопросы безопасности и поддержки. Минимальный набор здравого смысла выглядит так:
- не класть пароли и ключи прямо в YAML, а выносить их в .env или использовать Docker secrets;
- отдельно описывать окружения, не таскать dev-инструменты в прод-образы;
- следить за версиями образов и регулярно их обновлять, чтобы закрывать уязвимости;
- подключать нормальный мониторинг и логирование (Prometheus, Grafana, ELK или аналог), иначе любые проблемы придётся ловить «на ощупь».
Ограничения Docker Compose #
Compose сильно упрощает жизнь, но не решает вообще все задачи. Есть нюансы, о которых лучше помнить заранее:
- Не для огромных продакшн-систем. Для десятков и сотен сервисов удобнее уже полноценный оркестратор вроде Kubernetes или Swarm;
- Масштабирование в пределах одного хоста. Compose сам по себе не делает из нескольких серверов кластер;
- Риск смешать окружения. Если не аккуратно разделять конфиги, легко привезти dev-настройки в prod;
- Секреты без отдельной системы. Есть .env и Docker secrets, но это всё же не полноценный vault;
- Нет встроенного логирования и мониторинга. Всё надо организовывать внешними средствами;
- Зависимость от версии Docker. Некоторые опции могут вести себя по-разному в зависимости от того, какой Docker Engine крутится на хосте.
Для чего это бизнесу и клиенту #
С точки зрения бизнеса Docker Compose делает инфраструктуру более предсказуемой и дешёвой в обслуживании. В итоге приложения получают:
- Прозрачность. Вся схема описана в одном месте, проще разбираться, что где крутится;
- Управляемость. Любой член команды может поднять окружение по инструкции в пару команд, без долгих созвонов и ручных шагов;
- Быструю доставку. Новые окружения и обновления разворачиваются за минуты;
- Более безопасный процесс. Конфиги версионируются, а количество случайных различий между окружениями заметно падает.
В результате компании быстрее запускают проекты, проще вводят новых сотрудников в контекст и меньше зависят от того, «как именно Вася когда-то настроил сервер руками».
