Docker Compose: полное руководство по развертыванию
Узнайте, как быстро развернуть приложение на собственном сервере с Docker Compose: пошаговое полное руководство для новичков и профи.
Введение в Docker Compose
Docker Compose — это инструмент для определения и запуска многоконтейнерных приложений Docker. С помощью простого YAML-файла можно описать всю инфраструктуру вашего приложения: веб-сервер, базу данных, кэш и другие компоненты. Это позволяет запускать все приложение одной командой.
Установка Docker Compose
Установка Docker Compose на разных операционных системах
# Ubuntu/Debian
sudo apt update
sudo apt install docker.io
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# CentOS/RHEL/Fedora
sudo yum install docker
sudo systemctl start docker
sudo systemctl enable docker
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# macOS
brew install docker-compose
# Windows
# Установите Docker Desktop for Windows
# Проверка установки
docker-compose --versionОсновные концепции Docker Compose
Docker Compose — это инструмент оркестровки контейнеров, который позволяет определять и запускать многоконтейнерные приложения с помощью одного YAML-файла. Ключевые компоненты: сервисы, сети, тома, переменные окружения, сборка образов.
Структура docker-compose.yml
Базовая структура файла docker-compose.yml и пример конфигурации для веб-приложения
version: '3.8'
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./html:/usr/share/nginx/html
- ./ssl:/etc/nginx/ssl
depends_on:
- app
networks:
- app-network
app:
build: ./app
expose:
- "8000"
environment:
- NODE_ENV=production
- DB_HOST=db
- DB_PORT=5432
- DB_NAME=myapp
- DB_USER=user
- DB_PASSWORD=password
volumes:
- ./app:/app
depends_on:
- db
networks:
- app-network
db:
image: postgres:13
environment:
POSTGRES_DB: myapp
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- db-data:/var/lib/postgresql/data
networks:
- app-network
networks:
app-network:
driver: bridge
volumes:
db-data:Расширенные возможности Docker Compose
Работа с переменными окружения, сетями, томами, ограничениями ресурсов и другими продвинутыми функциями
# Работа с переменными окружения
version: '3.8'
services:
db:
image: postgres:${POSTGRES_VERSION:-13}
environment:
POSTGRES_USER: ${DB_USER:-user}
POSTGRES_PASSWORD: ${DB_PASSWORD:-password}
volumes:
- db-data:/var/lib/postgresql/data
# Управление сетями
networks:
frontend:
driver: bridge
backend:
driver: bridge
ipam:
config:
- subnet: 172.16.238.0/24
# Работа с томами
services:
db:
image: postgres:13
volumes:
# Использование именованного тома
- pgdata:/var/lib/postgresql/data
# Или привязка хост-директории
- ./data:/var/lib/postgresql/data:rw
# Установка ограничений ресурсов
services:
app:
image: myapp:latest
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.2'
memory: 256MОсновные команды Docker Compose
Основные команды для работы с Docker Compose: запуск сервисов, просмотр статуса, работа с логами, управление контейнерами и т.д.
# Запуск всех сервисов
docker-compose up -d
# Параметры:
# -d — запустить в фоновом режиме
# --build — пересобрать образы перед запуском
# --force-recreate — пересоздать контейнеры даже если конфигурация не изменилась
# Просмотр статуса сервисов
docker-compose ps
# Пересобрать образы
docker-compose build
# Просмотр логов
docker-compose logs
docker-compose logs -f web # Следить за логами в реальном времени
docker-compose logs --tail=50 web # Показать последние N строк
# Перезапуск сервисов
docker-compose restart app
# Остановка и удаление контейнеров
docker-compose down # Остановить и удалить контейнеры, сети, но не тома
docker-compose down -v # Остановить и удалить всё, включая тома
# Масштабирование сервисов
docker-compose up -d --scale app=3Развертывание приложений с помощью Docker Compose
Особенности использования Docker Compose для разработки и продакшена, использование в CI/CD
# Для разработки
version: '3.8'
services:
app:
build: .
volumes:
- .:/app # Монтирование всего проекта
environment:
- NODE_ENV=development
command: npm run dev
# Для продакшена
version: '3.8'
services:
app:
image: mycompany/myapp:${TAG:-latest}
restart: unless-stopped
environment:
- NODE_ENV=production
- DATABASE_URL=postgres://user:pass@db:5432/mydb
depends_on:
db:
condition: service_healthy
db:
image: postgres:13
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5Решение распространенных проблем
Как решать типичные проблемы при работе с Docker Compose: конфликты портов, проблемы с подключением к базе данных, проблемы с правами доступа и др.
# Проблема 1: Конфликт портов
# Решение: Измените пробрасываемые порты
services:
web:
ports:
- "8080:80" # Используйте другой порт хоста
# Проблема 2: Не удается подключиться к базе данных
# Проверьте сетевое взаимодействие
docker-compose exec app ping db
# Проверьте логи сервиса базы данных
docker-compose logs db
# Проблема 3: Проблемы с правами доступа
# Для настройки прав на хост-системе:
sudo chown -R 1000:1000 ./app
# Проблема 4: Не обновляются изменения в коде
# Используйте пересборку образа:
docker-compose up -d --build app
# Проблема 5: Недостаточно памяти
# Проверьте использование памяти:
docker stats
# Установите ограничения для сервисов:
services:
app:
deploy:
resources:
limits:
memory: 1GЛучшие практики и рекомендации
Рекомендации по организации проектов, оптимизации образов, безопасности и мониторингу при работе с Docker Compose
# Организация проекта
project/
├── docker-compose.yml
├── docker-compose.dev.yml
├── docker-compose.prod.yml
├── .env
├── services/
│ ├── web/
│ │ ├── Dockerfile
│ │ ├── package.json
│ │ └── ...
│ ├── app/
│ │ ├── Dockerfile
│ │ ├── package.json
│ │ └── ...
│ └── db/
│ ├── Dockerfile
│ └── ...
└── nginx/
├── nginx.conf
└── ...
# Оптимизация образов - многостадийная сборка
# Dockerfile.prod
FROM node:16 as builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
FROM node:16-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .
RUN npm run build
CMD ["npm", "start"]
# Безопасность - использование .env файлов для секретов
version: '3.8'
services:
app:
image: myapp:latest
environment:
- DATABASE_URL=${DATABASE_URL}Как я это чувствую, но единственное, что я делаю - это копирую docker-compose.yml и запускаю команду up -d
Введение
Docker Compose — это инструмент для определения и запуска многоконтейнерных приложений Docker. С помощью простого YAML-файла можно описать всю инфраструктуру вашего приложения: веб-сервер, базу данных, кэш и другие компоненты. Это позволяет запускать все приложение одной командой.
Многие разработчики сталкиваются с ситуацией, когда они просто копируют готовый docker-compose.yml файл из проекта в проект и запускают его с помощью команды docker-compose up -d. За кажущейся простотой этого процесса стоит мощная система оркестровки контейнеров. В этой статье мы рассмотрим все аспекты работы с Docker Compose: от установки до продвинутых сценариев использования.
Предварительные требования
Перед началом работы убедитесь, что у вас установлены:
- Docker (версия 20.10 или выше)
- Docker Compose (версия 1.29 или выше)
Проверить установку можно командами:
docker --version
docker-compose --version
Установка Docker Compose
Linux (Ubuntu/Debian)
# Обновление пакетов
sudo apt update
# Установка Docker
sudo apt install docker.io
# Установка Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# Создание символической ссылки (опционально)
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
Linux (CentOS/RHEL/Fedora)
# Установка Docker
sudo yum install docker
# Запуск и добавление в автозагрузку
sudo systemctl start docker
sudo systemctl enable docker
# Установка Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# Создание символической ссылки (опционально)
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
macOS
Используйте Homebrew:
brew install docker-compose
Windows
- Установите Docker Desktop for Windows
- Docker Compose будет включен в состав Docker Desktop
Проверка установки
docker-compose --version
Должна отображаться версия Docker Compose, например: docker-compose version 2.20.3
Основные концепции Docker Compose
Что такое Docker Compose?
Docker Compose — это инструмент для оркестровки контейнеров, который позволяет определять и запускать многоконтейнерные приложения с помощью одного YAML-файла. Он упрощает управление сложными системами, автоматизируя создание и запуск контейнеров, сетей и томов данных.
Ключевые компоненты Docker Compose
- Сервисы (Services) — контейнеры, выполняющие определенную функцию (веб-сервер, база данных, кэш и т.д.).
- Сети (Networks) — изолированные среды для обмена данными между сервисами.
- Тома (Volumes) — механизмы для постоянного хранения данных, которые сохраняются даже после остановки контейнера.
- Переменные окружения (Environment variables) — параметры конфигурации, которые можно передавать в контейнеры.
- Сборка образов (Build) — возможность создания образов Docker из Dockerfile.
Преимущества использования Docker Compose
- Простота: Определение всей инфраструктуры в одном файле
- Портативность: Легкое развертывание на любой машине с Docker
- Масштабируемость: Простое увеличение количества экземпляров сервисов
- Изоляция: Каждый сервис работает в своем изолированном контейнере
- Воспроизводимость: Простое воспроизведение идентичных окружений для разработки, тестирования и продакшена
Структура docker-compose.yml
Базовая структура файла
version: '3.8' # Версия формата Compose
services: # Определение сервисов
web:
# Конфигурация веб-сервиса
db:
# Конфигурация базы данных
networks: # Определение сетей (опционально)
app-network:
driver: bridge
volumes: # Определение томов (опционально)
db-data:
Версия файла
Версия YAML-формата определяет доступные возможности. Для современных проектов рекомендуется использовать '3.8'. Полный список доступных версий можно найти в официальной документации Docker Compose.
Определение сервисов
Сервис — это контейнер или группа контейнеров, выполняющих одинаковую функцию:
services:
web:
image: nginx:latest # Используем готовый образ
ports:
- "80:80" # Проброс портов
volumes:
- ./html:/usr/share/nginx/html # Монтирование тома
environment:
- ENV=production # Переменные окружения
Полный пример для веб-приложения
Рассмотрим пример полнофункционального веб-приложения с nginx, веб-приложением на Node.js и базой данных PostgreSQL:
version: '3.8'
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./html:/usr/share/nginx/html
- ./ssl:/etc/nginx/ssl
depends_on:
- app
networks:
- app-network
app:
build: ./app
expose:
- "8000"
environment:
- NODE_ENV=production
- DB_HOST=db
- DB_PORT=5432
- DB_NAME=myapp
- DB_USER=user
- DB_PASSWORD=password
volumes:
- ./app:/app
depends_on:
- db
networks:
- app-network
db:
image: postgres:13
environment:
POSTGRES_DB: myapp
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- db-data:/var/lib/postgresql/data
networks:
- app-network
redis:
image: redis:alpine
networks:
- app-network
volumes:
- redis-data:/data
networks:
app-network:
driver: bridge
volumes:
db-data:
redis-data:
Расширенные возможности Docker Compose
Работа с переменными окружения
Вместо жестко заданных значений используйте переменные окружения:
version: '3.8'
services:
db:
image: postgres:${POSTGRES_VERSION:-13}
environment:
POSTGRES_USER: ${DB_USER:-user}
POSTGRES_PASSWORD: ${DB_PASSWORD:-password}
volumes:
- db-data:/var/lib/postgresql/data
volumes:
db-data:
Создайте файл .env в той же директории:
POSTGRES_VERSION=13
DB_USER=myuser
DB_PASSWORD=mypassword
Управление сетями
По умолчанию Docker Compose создает сеть с именем <project_name>_default. Можно определить собственные сети:
networks:
frontend:
driver: bridge
backend:
driver: bridge
ipam:
config:
- subnet: 172.16.238.0/24
Работа с томами
Тома позволяют сохранять данные между перезапусками контейнеров:
services:
db:
image: postgres:13
volumes:
# Использование именованного тома
- pgdata:/var/lib/postgresql/data
# Или привязка хост-директории
- ./data:/var/lib/postgresql/data:rw
volumes:
pgdata:
driver: local
Установка ограничений ресурсов
Для предотвращения истощения ресурсов хоста:
services:
app:
image: myapp:latest
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.2'
memory: 256M
Настройка перезапуска контейнеров
services:
web:
image: nginx:latest
restart: unless-stopped # Политика перезапуска
Доступные политики перезапуска:
no- не перезапускать (по умолчанию)always- всегда перезапускатьon-failure- перезапускать при ошибкеunless-stopped- перезапускать, только если контейнер не был остановлен вручную
Конфигурация здоровья сервисов
services:
app:
image: myapp:latest
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
Команды Docker Compose
Основные команды
Запуск всех сервисов:
docker-compose up -d
Параметры:
-d— запустить в фоновом режиме--build— пересобрать образы перед запуском--force-recreate— пересоздать контейнеры даже если конфигурация не изменилась--remove-orphans— удалить контейнеры, которые больше не определены в compose-файле--no-recreate— не пересоздавать контейнеры, если они уже существуют
Просмотр статуса сервисов:
docker-compose ps
Работа с образами
Пересобрать образы:
docker-compose build
Просмотреть список образов:
docker-compose images
Просмотр логов
Для мониторинга работы приложений:
# Показать логи всех сервисов
docker-compose logs
# Показать логи конкретного сервиса
docker-compose logs web
# Следить за логами в реальном времени
docker-compose logs -f web
# Показать последние N строк логов
docker-compose logs --tail=50 web
Управление сервисами
Перезапуск сервисов:
docker-compose restart app
Обновление сервисов:
docker-compose up -d --no-deps app
Остановка и удаление контейнеров:
# Остановить и удалить контейнеры, сети, но не тома
docker-compose down
# Остановить и удалить всё, включая тома
docker-compose down -v
# Остановка без удаления контейнеров
docker-compose stop
Масштабирование сервисов
Для увеличения числа экземпляров сервиса:
# Запустить 3 экземпляра сервиса
docker-compose up -d --scale app=3
# Установить количество экземпляров по умолчанию
docker-compose scale app=3
Работа с контейнерами
Запустить команду в контейнере:
docker-compose exec app ls -l /app
Копирование файлов между хостом и контейнером:
# Копировать файлы из контейнера на хост
docker-compose cp app:/app/config ./config
# Копировать файлы с хоста в контейнер
docker-compose cp ./config app:/app/config
Пауза и возобновление работы
# Приостановить работу всех сервисов
docker-compose pause
# Возобновить работу всех сервисов
docker-compose unpause
Развертывание приложений
Для разработки
Для разработки часто монтируют исходный код как том, чтобы изменения сразу применялись без пересборки образа:
version: '3.8'
services:
app:
build: .
volumes:
- .:/app # Монтирование всего проекта
environment:
- NODE_ENV=development
command: npm run dev
Для продакшена
Для продакшена рекомендуется использовать готовые образы из Docker Hub или собственного registry:
version: '3.8'
services:
app:
image: mycompany/myapp:${TAG:-latest}
restart: unless-stopped
environment:
- NODE_ENV=production
- DATABASE_URL=postgres://user:pass@db:5432/mydb
depends_on:
db:
condition: service_healthy
db:
image: postgres:13
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
Использование Docker Compose в CI/CD
Пример использования Docker Compose в CI/CD конвейере:
# .gitlab-ci.yml
stages:
- test
- build
- deploy
test:
stage: test
services:
- docker:dind
script:
- docker-compose -f docker-compose.test.yml up -d
- docker-compose exec app npm test
- docker-compose down -v
build:
stage: build
services:
- docker:dind
script:
- docker build -t myapp:$CI_COMMIT_SHA .
- docker tag myapp:$CI_COMMIT_SHA myapp:latest
- docker push myapp:$CI_COMMIT_SHA
- docker push myapp:latest
deploy:
stage: deploy
script:
- docker-compose down
- docker-compose pull
- docker-compose up -d
Решение распространенных проблем
Проблема 1: Конфликт портов
Симптом: Ошибка "port is already allocated"
Решение: Измените пробрасываемые порты в docker-compose.yml:
services:
web:
ports:
- "8080:80" # Используйте другой порт хоста
или остановите процесс, использующий порт:
sudo lsof -ti:80 | xargs kill -9
Проблема 2: Не удается подключиться к базе данных
Симптом: Ошибка подключения к базе данных после запуска
Решение:
- Проверьте, что сервис базы данных запущен:
docker-compose ps
- Убедитесь, что используете правильное имя хоста в конфигурации приложения:
services:
app:
environment:
DB_HOST: db # Имя сервиса из docker-compose.yml
- Проверьте сетевое взаимодействие:
docker-compose exec app ping db
- Проверьте логи сервиса базы данных:
docker-compose logs db
Проблема 3: Проблемы с правами доступа
Симптом: Ошибка "Permission denied" при работе с томами
Решение: Используйте именованные тома или настройте правильные права для монтируемых директорий:
services:
app:
volumes:
- ./app:/app:ro # Только чтение
- /path/to/data:/data:rw # Чтение и запись с правильными правами
Для настройки прав на хост-системе:
sudo chown -R 1000:1000 ./app
Проблема 4: Не обновляются изменения в коде
Симптом: Изменения в коде приложения не видны после перезапуска
Решение:
- Используйте пересборку образа:
docker-compose up -d --build app
- Для разработки монтируйте исходный код как том:
services:
app:
build: .
volumes:
- ./app:/app # Монтирование исходного кода
- Для Node.js приложений может потребоваться установка
nodemon:
services:
app:
build: .
command: nodemon server.js
volumes:
- ./app:/app
Проблема 5: Недостаточно памяти
Симптом: Ошибка "container killed" из-за нехватки памяти
Решение:
- Проверьте использование памяти:
docker stats
- Установите ограничения для сервисов:
services:
app:
deploy:
resources:
limits:
memory: 1G
- Увеличьте ресурсы Docker Desktop (для macOS/Windows) или перезапустите демон Docker с правильными настройками (для Linux).
Проблема 6: Конфликты версий зависимостей
Симптом: Ошибки при запуске из-за конфликтов версий
Решение: Используйте многостадийную сборку для изоляции зависимостей:
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile.prod
depends_on:
- db
environment:
- NODE_ENV=production
db:
image: postgres:13
volumes:
- db-data:/var/lib/postgresql/data
volumes:
db-data:
# Dockerfile.prod
FROM node:16 as builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
FROM node:16-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .
RUN npm run build
CMD ["npm", "start"]
Лучшие практики и рекомендации
Организация проектов
-
Разделяйте файлы для разных окружений:
docker-compose.yml- базовая конфигурацияdocker-compose.dev.yml- для разработкиdocker-compose.prod.yml- для продакшена
-
Используйте файлы
.envдля хранения секретов и конфигурационных данных -
Создавайте отдельные директории для каждого сервиса
project/
├── docker-compose.yml
├── docker-compose.dev.yml
├── docker-compose.prod.yml
├── .env
├── services/
│ ├── web/
│ │ ├── Dockerfile
│ │ ├── package.json
│ │ └── ...
│ ├── app/
│ │ ├── Dockerfile
│ │ ├── package.json
│ │ └── ...
│ └── db/
│ ├── Dockerfile
│ └── ...
└── nginx/
├── nginx.conf
└── ...
Оптимизация образов
-
Используйте многостадийную сборку для уменьшения размера финального образа
-
Используйте конкретные версии образов вместо
latest -
Минимизируйте количество слоев в Dockerfile
-
Очищайте кэш пакетных менеджеров
Безопасность
-
Не храните секреты в docker-compose.yml, используйте
.envфайлы -
Используйте официальные образы из Docker Hub или доверенных источников
-
Регулярно обновляйте образы для устранения уязвимостей
-
Запускайте контейнеры с минимально необходимыми привилегиями
Мониторинг и логирование
-
Настройте централизованное логирование
-
Используйте healthcheck для мониторинга состояния сервисов
-
Ограничивайте ресурсы для предотвращения истощения хоста
-
Используйте инструменты мониторинга вроде Prometheus и Grafana
Заключение
Docker Compose — это мощный инструмент, который значительно упрощает работу с многоконтейнерными приложениями. Хотя запуск приложения действительно может сводиться к копированию готового docker-compose.yml и выполнению команды docker-compose up -d, глубокое понимание принципов работы Docker Compose поможет вам эффективнее использовать этот инструмент и решать возникающие проблемы.
В этой статье мы рассмотрели все аспекты работы с Docker Compose: от установки и базовых концепций до продвинутых сценариев использования и решения распространенных проблем. Теперь вы можете не только запускать приложения с помощью Docker Compose, но и настраивать, оптимизировать и отлаживать их.
Продолжайте экспериментировать с различными конфигурациями, создавайте свои собственные docker-compose.yml файлы и не бойтесь обращаться к официальной документации Docker Compose для получения дополнительной информации.