Зачем нужен Docker Compose
Один контейнер можно запустить одной командой, но реальный проект редко состоит из одного процесса. Приложению нужны база данных, кэш, очередь, прокси или отдельный воркер. Docker Compose описывает эти сервисы в одном YAML-файле и позволяет запускать их согласованно.
Главная польза Compose не в короткой команде, а в воспроизводимости. Конфигурация хранится рядом с кодом, разработчик видит порты, сети, переменные и тома, а новый участник команды может поднять окружение без ручной настройки десятка программ.
Установка и проверка
В современных версиях Docker Compose поставляется как плагин Docker и вызывается через команду docker compose. Старый вариант с дефисом — docker-compose — всё ещё встречается в старых проектах, но смешивать синтаксис и версии не стоит.
- Установите Docker Desktop на Windows или macOS либо Docker Engine и плагин Compose на Linux.
- Перезапустите терминал, чтобы команда появилась в PATH.
- Проверьте версии командами
docker --versionиdocker compose version. - Запустите тестовый контейнер и убедитесь, что демон Docker отвечает без ошибки доступа.
Если команда не найдена, проверьте, что Docker запущен, а в Linux пользователь входит в группу docker или запускает команды с нужными правами. Не копируйте случайные установочные скрипты из форумов: для рабочей машины используйте официальные пакеты и инструкции вашей системы.
Как устроен файл compose.yaml
Файл описывает сервисы проекта. Минимальная структура включает имя сервиса, образ или сборку, порты, переменные и тома. Версию формата обычно не требуется указывать в новых Compose, а устаревшее поле может давать предупреждение.
services:
web:
image: nginx:alpine
ports:
- "8080:80"
db:
image: postgres:16
environment:
POSTGRES_DB: app
POSTGRES_USER: app
POSTGRES_PASSWORD: change-me
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:
В примере два сервиса находятся в общей сети Compose и могут обращаться друг к другу по именам web и db. Порт слева виден на компьютере, порт справа работает внутри контейнера. Поэтому запись 8080:80 означает: откройте в браузере порт 8080 хоста и передайте трафик на 80 внутри контейнера.
Первый запуск и остановка
| Команда | Назначение | Когда использовать |
|---|---|---|
docker compose up |
Создать и запустить сервисы в текущем окне | Когда нужны логи на экране |
docker compose up -d |
Запустить в фоне | Для обычной локальной работы |
docker compose ps |
Показать состояние контейнеров | После запуска или перезапуска |
docker compose logs -f web |
Следить за логами выбранного сервиса | При диагностике |
docker compose stop |
Остановить контейнеры, сохранив их | Перед перерывом в работе |
docker compose down |
Остановить и удалить контейнеры сети | Чтобы собрать окружение заново |
После сохранения compose.yaml запускайте проект из каталога, где лежит файл, или указывайте путь через параметр -f. Если файл называется иначе, Compose не всегда найдёт его автоматически.
Переменные окружения и секреты
Пароли и ключи не стоит хранить прямо в репозитории. Для локальной разработки удобно создать файл .env, а в compose.yaml использовать подстановку:
services:
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
Добавьте .env в исключения Git и храните пример без секретов, например .env.example. На CI значения передают через секреты системы сборки. Проверяйте, какие переменные действительно попали в контейнер, но не публикуйте вывод с паролями в задаче или логе.
Тома и сохранность данных
Контейнер можно удалить и создать заново, а данные базы должны пережить этот цикл. Для этого используют именованный том. Он хранится отдельно от слоя контейнера и подключается к нужному пути внутри сервиса.
Удаление через docker compose down обычно сохраняет именованные тома. Команда с флагом --volumes удалит и их, поэтому применяйте её только когда действительно хотите начать с пустой базы. Перед очисткой сделайте резервную копию, особенно если в томе лежат рабочие данные.
Сборка собственного образа
Если проект содержит исходники, вместо image укажите build и путь к Dockerfile:
services:
app:
build: .
ports:
- "8000:8000"
volumes:
- .:/app
Монтирование каталога ускоряет разработку, но может скрыть файлы, которые были скопированы в образ. Для продакшена чаще собирают неизменяемый образ и не подключают исходники с хоста. Команды docker compose build и docker compose up --build помогают обновить образ после изменения Dockerfile.
Типичные ошибки и порядок проверки
- Порт занят. Найдите процесс, который использует порт, или измените левую часть mapping.
- Контейнер сразу завершается. Посмотрите
docker compose logs имя-сервисаи проверьте команду запуска. - Сервис не видит базу. Внутри Compose используйте имя сервиса и внутренний порт, а не localhost хоста.
- Данные исчезли. Проверьте, подключён ли том и не использовался ли флаг удаления томов.
- Изменения не применились. Пересоберите образ, а затем перезапустите нужный сервис.
Если проект перестал запускаться после обновления, сохраните вывод docker compose config, список образов и последние строки логов. Это помогает отделить ошибку YAML от проблемы приложения и не чинить систему наугад.
Безопасная привычка для команды
Храните compose-файл в репозитории, фиксируйте версии образов, описывайте обязательные переменные и добавляйте короткую инструкцию запуска в README. Не открывайте наружу административные порты без необходимости и не используйте пароль из примера в реальной среде.
После того как базовый запуск работает, можно отдельно настроить healthcheck, профили и ограничения ресурсов. Начинайте с простой конфигурации: прозрачный файл легче проверить, чем набор непонятных оптимизаций.
Командная работа и обновление конфигурации
Compose-файл должен быть понятен человеку, который увидит его впервые. Давайте сервисам говорящие имена, храните пример переменных рядом с проектом и фиксируйте команды запуска в README. Если команда меняет порт, версию базы или путь тома, описывайте это в истории изменений.
Не используйте latest для важных сервисов без причины: обновление образа может изменить поведение проекта. Закреплённый тег упрощает повторный запуск и помогает понять, что именно поменялось после обновления.
Локальная разработка и CI
Один и тот же compose-файл можно использовать локально и в CI, но секреты, тома и внешние порты для этих сред обычно различаются. Удобно разделить базовый файл и дополнительный override для разработки. В CI оставляйте только необходимые сервисы и проверяйте, что после тестов контейнеры останавливаются.
Перед коммитом полезно выполнить проверку итоговой конфигурации: Compose сообщит о несуществующих переменных, ошибках отступов и конфликтующих параметрах. Это дешевле, чем искать проблему после загрузки на сервер.
Минимальный проект для практики
Для первого знакомства удобно собрать сервис из приложения и базы данных, открыть один порт и сохранить данные в именованный том. Такой проект показывает почти все базовые возможности Compose, но остаётся достаточно маленьким для диагностики. После запуска измените переменную окружения, пересоберите образ и проверьте, что данные базы не исчезли.
Читайте также: как читать логи сервера и как подойти к юнит-тестам новичку.