Docker Compose — инструмент для определения и запуска многоконтейнерных приложений. Вместо ручного запуска каждого контейнера конфигурация приложения описывается в YAML-файле, после чего весь стек можно запустить одной командой.
Compose особенно полезен для веб-приложений, где одновременно нужны несколько сервисов: например, Nginx, PHP, PostgreSQL и Redis.
Зачем нужен Docker Compose
Представим сайт, состоящий из:
- Nginx;
- PHP-FPM;
- PostgreSQL;
- Redis.
Без Compose пришлось бы отдельно создавать четыре контейнера, настраивать сети, volumes, переменные окружения и зависимости.
Compose позволяет описать инфраструктуру декларативно.
Например:
services:
nginx:
image: nginx:alpine
app:
image: php:8.4-fpm
postgres:
image: postgres:18
redis:
image: redis:alpine
После этого стек запускается:
docker compose up -d
Compose управляет сервисами, сетями и volumes из одного конфигурационного файла.
Файл compose.yaml
Современный Compose использует Compose Specification. Старые версии формата 2.x и 3.x были объединены в единую спецификацию.
Базовый файл:
services:
web:
image: nginx:alpine
Запуск:
docker compose up -d
Проверка:
docker compose ps
Остановка:
docker compose down
Основные команды
Запустить проект:
docker compose up -d
Остановить:
docker compose stop
Остановить и удалить контейнеры и сеть:
docker compose down
Посмотреть контейнеры:
docker compose ps
Посмотреть логи:
docker compose logs
Следить за логами:
docker compose logs -f
Перезапустить сервис:
docker compose restart web
Выполнить команду внутри контейнера:
docker compose exec web sh
Эти команды позволяют управлять практически всем жизненным циклом Compose-приложения.
Compose и порты
Чтобы открыть порт контейнера наружу:
services:
web:
image: nginx:alpine
ports:
- "8080:80"
Первое число — порт хоста, второе — порт внутри контейнера.
После запуска:
localhost:8080
попадет на порт 80 контейнера.
Compose и переменные окружения
Настройки можно передавать через environment:
services:
app:
image: my-app
environment:
APP_ENV: production
DB_HOST: postgres
Для секретов production-системы лучше использовать специальные механизмы хранения секретов, а не записывать пароли непосредственно в Compose-файл.
Docker Compose и volumes
Базу данных нельзя рассчитывать хранить только внутри файловой системы контейнера.
Для PostgreSQL можно использовать volume:
services:
postgres:
image: postgres:18
volumes:
- postgres-data:/var/lib/postgresql
volumes:
postgres-data:
Volumes предназначены для постоянного хранения данных вне жизненного цикла конкретного контейнера.
Подробнее — в статье «Docker volumes».
Docker Compose и networks
Compose автоматически создает сеть проекта. Сервисы в ней могут обращаться друг к другу по имени сервиса.
Например:
services:
app:
image: my-app
db:
image: postgres:18
Приложение может обращаться к базе по адресу:
db:5432
IP-адрес контейнера указывать не нужно.
Docker Compose и Dockerfile
Compose может собирать собственные образы.
services:
app:
build: .
В каталоге проекта:
Dockerfile
compose.yaml
src/
Команда:
docker compose build
соберет образ.
Подробнее о Dockerfile — в статье «Dockerfile: создание собственного образа».
Зависимости между сервисами
Можно описать зависимость:
services:
app:
depends_on:
- postgres
postgres:
image: postgres:18
Однако depends_on не означает, что база данных уже полностью готова принимать соединения. Для production-сценариев полезно использовать healthcheck и корректную обработку повторных подключений.
Compose в production
Compose можно использовать не только локально. Docker описывает сценарий развертывания Compose-приложений на одном сервере. Для production часто создают отдельный файл конфигурации, например compose.production.yaml.
Например:
docker compose \
-f compose.yaml \
-f compose.production.yaml \
up -d
В production стоит отдельно продумать:
- volumes;
- backup;
- логи;
- restart policy;
- мониторинг;
- обновление образов;
- секреты;
- ограничения ресурсов.
Итог
Docker Compose удобен, когда приложение состоит из нескольких контейнеров. Он объединяет конфигурацию сервисов, сетей и хранилищ в одном проекте.
Следующий логичный шаг — разобраться с volumes и networks, поскольку именно они отвечают за хранение данных и взаимодействие контейнеров.
Читайте также:

