Docker Compose — это инструмент для определения и запуска многоконтейнерных приложений Docker. Вместо того чтобы вручную запускать каждый контейнер отдельной командой docker run с десятком флагов, вы описываете всю инфраструктуру — сервисы, сети, тома — в одном декларативном YAML-файле. Это превращает сложный процесс оркестровки в простую команду docker compose up, что критически важно для DevOps-инженеров и системных администраторов, которые ценят воспроизводимость, контроль и экономию времени.
В этом руководстве вы получите готовый, проверенный на практике файл docker-compose.yml для типового стека «веб-сервер + база данных», пошаговую инструкцию по его запуску и глубокое объяснение ключевых аспектов: от сборки образов через секцию build до настройки сетевого взаимодействия между контейнерами. Материал основан на реальном опыте и закрывает основные страхи специалистов: «Сработает ли это в моем случае?» и «Не упустил ли я важный шаг?».
Что такое Docker Compose и зачем он нужен для многоконтейнерных приложений
Работа с несколькими контейнерами через отдельные команды docker run быстро становится неуправляемой. Представьте запуск простого веб-приложения с Nginx, PostgreSQL и Redis:
docker run -d --name db \
-e POSTGRES_PASSWORD=secret \
-v pgdata:/var/lib/postgresql/data \
postgres:16
docker run -d --name cache \
redis:alpine
docker run -d --name web \
--link db:db --link cache:cache \
-p 80:80 \
-v $(pwd)/app:/app \
my-web-app:latest
Проблемы очевидны: команды длинные и сложные для воспроизведения; легко ошибиться в порядке запуска или параметрах сети; нет единого представления о приложении как о целом. Docker Compose решает эти проблемы, предлагая декларативный подход. Вы описываете что должно работать (сервисы, их конфигурация, связи), а инструмент заботится о как это запустить. Основные выгоды:
- Единый источник истины: Вся инфраструктура описана в файле
docker-compose.yml, который можно добавить в систему контроля версий. - Автоматизация сборки и запуска: Одна команда
docker compose upсобирает образы (при необходимости) и запускает все сервисы в правильном порядке с учетом зависимостей. - Упрощенное управление сетями и томами: Compose автоматически создает изолированную сеть для сервисов и позволяет декларативно управлять томами для данных.
Это не просто удобство — это стандарт для разработки, тестирования и развертывания современных приложений, который снижает операционные риски и ускоряет работу. Для более глубокого понимания основ Docker, рекомендуем ознакомиться с практическим гайдом по архитектуре Docker для DevOps и системных администраторов.
От ручного запуска контейнеров к декларативной конфигурации
Эволюция от императивного (команды) к декларативному (YAML-файл) подходу — это переход от хаоса к контролю. Возражение «Я и так могу запустить несколько контейнеров скриптом» теряет силу, когда требуется обеспечить воспроизводимость на разных окружениях (разработка, staging, production), управлять версиями конфигурации и минимизировать человеческий фактор. Файл docker-compose.yml — это документация и исполняемый код в одном лице.
Создаем и разбираем docker-compose.yml: от структуры до рабочего примера
Практическая ценность руководства — в предоставлении готового, работающего инструмента. Ниже приведен полный пример файла docker-compose.yml для стека, состоящего из веб-сервера Nginx и базы данных PostgreSQL. Этот пример можно сразу скопировать, адаптировать под свои нужды и запустить.
version: '3.8'
services:
# Сервис базы данных PostgreSQL
db:
image: postgres:16-alpine # Используем конкретный тег для контроля версий
container_name: app_postgres
restart: unless-stopped
environment:
POSTGRES_DB: myappdb # Имя базы данных, создаваемой при первом запуске
POSTGRES_USER: appuser # Пользователь БД
POSTGRES_PASSWORD: ${DB_PASSWORD} # Пароль берется из переменной окружения
volumes:
- postgres_data:/var/lib/postgresql/data # Постоянное хранение данных
networks:
- app-network
# Опционально: проверка здоровья сервиса
healthcheck:
test: ["CMD-SHELL", "pg_isready -U appuser"]
interval: 10s
timeout: 5s
retries: 5
# Сервис веб-приложения (пример с кастомным образом)
web:
build: ./app # Собираем образ из Dockerfile в директории ./app
container_name: app_web
restart: unless-stopped
depends_on:
db:
condition: service_healthy # Ждем, пока БД не станет здоровой
environment:
DATABASE_URL: postgresql://appuser:${DB_PASSWORD}@db:5432/myappdb
volumes:
- ./app:/app # Монтируем код для разработки (hot-reload)
networks:
- app-network
ports:
- "8080:80" # Пробрасываем порт 80 контейнера на порт 8080 хоста
# Обратный прокси-сервер Nginx
proxy:
image: nginx:alpine
container_name: app_nginx
restart: unless-stopped
depends_on:
- web
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d:ro # Монтируем конфигурацию Nginx
networks:
- app-network
ports:
- "80:80"
- "443:443"
volumes:
postgres_data: # Декларативное объявление именованного тома
networks:
app-network: # Декларативное создание пользовательской сети
driver: bridge
Этот файл описывает три сервиса, которые будут работать в единой изолированной сети app-network. Данные PostgreSQL сохраняются в именованном томе postgres_data, который не удалится при остановке контейнеров.
Готовый пример: веб-приложение с PostgreSQL
Пример выше решает частую задачу — развертывание веб-приложения с базой данных. Ключевые моменты, на которые стоит обратить внимание:
- Имена сервисов (
db,web,proxy): Они же становятся именами хостов (DNS-именами) во внутренней сети Docker, что позволяет контейнерам обращаться друг к другу по имени (например, строке подключенияhost=db port=5432). - Переменные окружения: Секция
environmentкритически важна для конфигурации. Пароль вынесен в переменную${DB_PASSWORD}, которая должна быть определена в файле.envв той же директории. Никогда не храните секреты прямо в YAML-файле. - Volumes: Том
postgres_dataгарантирует сохранность данных БД между перезапусками контейнеров. Монтирование директории./appв сервисwebполезно на этапе разработки. - Проброс портов (
ports): Сервисproxyпубликует порт 80 на хосте, направляя трафик к внутренним сервисам.
Ключевые директивы services: image, build, ports, environment
Понимание основных директив позволяет гибко модифицировать конфигурацию:
image:Указывает готовый образ из реестра (Docker Hub). Всегда используйте конкретные теги (postgres:16-alpine), а не плавающийlatest, для обеспечения воспроизводимости.build:Задает контекст для сборки образа из Dockerfile. В примере для сервисаwebобраз будет собран изDockerfileв директории./app. Можно указать конкретный файл:build: context: ./app dockerfile: Dockerfile.prod.ports:Пробрасывает порты с хоста в контейнер в формате"HOST:CONTAINER". Для публикации порта только во внутренней сети Docker используйте только номер порта контейнера:"5432".environment:Задает переменные окружения. Можно использовать списокVAR=valueили словарь. Для управления секретами лучше использовать специальную секциюsecretsили внешний файл.env.
Для перехода от разработки к production-окружению с помощью Docker изучите полное руководство по безопасному деплою, мониторингу и логированию.
Пошаговое руководство по запуску: от файла до работающего приложения
Четкий алгоритм действий убирает неопределенность и дает уверенность. Предположим, вы сохранили приведенный выше YAML-файл как docker-compose.yml в отдельной директории проекта.
Сборка образов и запуск сервисов
- Подготовка переменных окружения: Создайте в той же директории файл
.envи задайте в нем необходимые переменные, например:DB_PASSWORD=StrongPassw0rd! - Проверка конфигурации (опционально, но рекомендуется): Выполните команду для валидации и просмотра итогового конфига:
Эта команда выведет обработанный файл конфигурации, что помогает найти синтаксические ошибки и убедиться в правильности подстановки переменных.docker compose config - Сборка и запуск: Основная команда для старта:
docker compose up --build -d--build— принудительно пересобирает образы, даже если они уже существуют (для сервисов с директивойbuild).-d(detached) — запускает контейнеры в фоновом режиме.- Без флага
-dвы увидите объединенные логи всех сервисов в текущем терминале.
Compose автоматически создаст сеть, тома и запустит сервисы в порядке, определенном зависимостями (depends_on).
Базовый мониторинг и управление состоянием
После запуска необходимо убедиться, что все сервисы работают корректно.
- Проверка статуса:
Команда покажет список сервисов, их состояние (Up, Exit), порты. Это первое действие при диагностике проблем.docker compose ps - Просмотр логов: Для наблюдения за логами конкретного сервиса (например,
web):
Флагdocker compose logs -f web-f(follow) позволяет отслеживать логи в реальном времени. Просмотр логов — основной способ понять, почему контейнер завершил работу сразу после старта. - Остановка и очистка: Чтобы остановить приложение и удалить контейнеры, сети (но не тома), выполните:
Для удаления вместе с анонимными томами, созданными сервисами, добавьте флагdocker compose down-v. Именованные тома (объявленные в секцииvolumes) при этом не удаляются, что сохраняет данные БД.docker compose down -v
Обеспечение связи между контейнерами: сети Docker Compose
Ключевой принцип сетевого взаимодействия в Docker Compose прост: сервисы, объявленные в одном файле docker-compose.yml, по умолчанию подключаются к одной внутренней сети (bridge) и могут находить друг друга по имени сервиса.
Имена сервисов как DNS-имена
Docker Compose автоматически настраивает встроенный DNS-сервер. В примере выше контейнер сервиса web может подключиться к базе данных, используя в строке подключения хост db и порт 5432. Это работает, потому что оба сервиса находятся в одной пользовательской сети app-network. Имя сервиса (db) резолвится во внутренний IP-адрес контейнера.
Это избавляет от необходимости использовать устаревший флаг --link или вручную прописывать статические IP-адреса. Для более сложных сценариев, таких как настройка статических IP или работа с несколькими сетями, обратитесь к руководству по продвинутым сетевым конфигурациям и безопасности Docker.
Управление версиями образов и оптимизация сборки
Контроль за версиями образов — залог стабильности и воспроизводимости вашего окружения.
- Используйте конкретные теги: Всегда указывайте полный тег образа (
postgres:16-alpine,nginx:1.25-alpine). Использование тегаlatestможет привести к неожиданным обновлениям и поломкам при повторном развертывании. - Стратегия тегирования для своих образов: При сборке своих образов через
buildиспользуйте схему тегирования, например, с хэшем коммита или версией приложения.
Сборка своих образов через секцию build
Директива build интегрирует процесс сборки в workflow Compose. Docker использует кэширование слоев для ускорения повторных сборок. Чтобы принудительно пересобрать образ без кэша, используйте:
docker compose build --no-cache web
Для оптимизации скорости сборки и размера образа обязательно используйте файл .dockerignore в контексте сборки, чтобы исключить из образа ненужные файлы (например, node_modules, .git).
Чтобы увидеть список образов, включая собранные через Compose, выполните:
docker images
Практические советы и частые проблемы
Основано на реальном опыте развертывания.
- Файл
.env: Используйте его для хранения переменных окружения, специфичных для данного развертывания (пароли, ключи API). Не коммитьте его в Git. Добавьте.envв.gitignore. - Контейнер падает сразу после старта: Первым делом смотрите логи:
docker compose logs [service_name]. Частые причины: ошибка в переменных окружения, отсутствие зависимого сервиса (используйтеdepends_onсcondition: service_healthy), ошибка в точке входа (CMD) Dockerfile. - Обновление конфигурации: После изменения
docker-compose.ymlвыполнитеdocker compose up -d. Compose остановит и пересоздаст только те сервисы, конфигурация которых изменилась. - Миграция с версии 2 на версию 3: Современные версии Docker Engine и Compose используют схему версии 3.x. Основное отличие — версия 3.x оптимизирована для работы с Docker Swarm и имеет несколько измененных или удаленных параметров (например,
volume_driver). Для standalone-использования достаточно указатьversion: '3.8'. - Управление в кластере: Если ваш следующий шаг — оркестрация контейнеров на нескольких хостах, изучите практическое руководство по Docker Swarm для системных администраторов как более простую альтернативу Kubernetes.
Docker Compose — это мощный инструмент, который превращает управление сложной инфраструктурой из рутины в предсказуемый и контролируемый процесс. Начните с готового примера из этой статьи, адаптируйте его под свои задачи, и вы значительно ускорите циклы разработки и развертывания.