Автоматическое развёртывание с GitHub Actions: настройка CI/CD Pipeline
CI/CD с GitHub Actions: сборка и публикация Docker-образов, развёртывание на сервер по SSH, автотесты, управление секретами и оптимизация workflow.
Многоконтейнерные приложения с Docker Compose: зависимости сервисов, переменные окружения, health check, масштабирование и запуск в production.
Docker Compose — инструмент, позволяющий определять и управлять несколькими Docker-контейнерами с помощью единого YAML-файла. Он незаменим для микросервисных архитектур, веб-приложений и сред разработки.
С Docker Compose вы можете:
docker-compose.ymlDocker Compose v2 запускается командой docker compose (без дефиса) и интегрирован в Docker CLI. Старая команда docker-compose по-прежнему поддерживается.
version: '3.9'
services:
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html:ro
restart: unless-stopped
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: секретный_пароль
MYSQL_DATABASE: моё_приложение
volumes:
- db_data:/var/lib/mysql
restart: unless-stopped
volumes:
db_data:
services:
app:
build:
context: ./app
dockerfile: Dockerfile
image: моё-приложение:latest
container_name: app-container
ports:
- "3000:3000"
environment:
NODE_ENV: production
DB_HOST: database
depends_on:
database:
condition: service_healthy
networks:
- app-network
restart: unless-stopped
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
volumes:
# Именованный том (управляется Docker)
db_data:
driver: local
# Внешний том (предварительно созданный)
existing_volume:
external: true
# Пользовательские параметры драйвера
nfs_volume:
driver: local
driver_opts:
type: nfs
o: addr=192.168.1.100,rw
device: ":/nfs/share"
networks:
# Стандартная bridge-сеть
app-network:
driver: bridge
# С пользовательской подсетью
custom-net:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
# Внешняя сеть
existing-net:
external: true
Управляйте порядком запуска сервисов с помощью depends_on:
services:
web:
image: nginx:alpine
depends_on:
api:
condition: service_healthy
db:
condition: service_healthy
api:
build: ./api
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
depends_on:
db:
condition: service_healthy
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: пароль
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
depends_on контролирует только порядок запуска. Без condition: service_healthy нельзя гарантировать готовность сервиса.
services:
app:
image: моё-приложение:latest
environment:
- NODE_ENV=production
- PORT=3000
- DB_HOST=database
- DB_PORT=5432
services:
app:
image: моё-приложение:latest
env_file:
- .env
- .env.production
Файл .env:
# .env
NODE_ENV=production
DB_HOST=database
DB_PORT=5432
DB_NAME=моё_приложение
DB_USER=пользователь
DB_PASS=секретный_пароль
JWT_SECRET=очень_секретный_ключ
REDIS_URL=redis://redis:6379
Добавьте .env в .gitignore. Никогда не коммитьте конфиденциальную информацию в Git.
Вы можете горизонтально масштабировать сервисы с Docker Compose:
# Запустить сервис api с 3 экземплярами
docker compose up -d --scale api=3
# Изменить количество запущенных экземпляров
docker compose up -d --scale api=5
# Масштабировать конкретный сервис
docker compose scale api=3 worker=2
Конфигурация балансировщика нагрузки для масштабирования:
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- api
api:
build: ./api
# Не определяйте ports — nginx будет маршрутизировать
expose:
- "3000"
environment:
NODE_ENV: production
Используйте override-файлы для разных окружений:
# docker-compose.override.yml (разработка)
services:
app:
build:
context: .
target: development
volumes:
- .:/app
- /app/node_modules
environment:
NODE_ENV: development
command: npm run dev
db:
ports:
- "5432:5432" # Открыть наружу в разработке
# docker-compose.prod.yml (production)
services:
app:
image: registry.example.com/моё-приложение:latest
restart: always
deploy:
replicas: 3
resources:
limits:
cpus: '1.0'
memory: 1G
Использование:
# Разработка (override применяется автоматически)
docker compose up -d
# Production
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
version: '3.9'
services:
nginx:
image: nginx:1.25-alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- certbot_data:/etc/letsencrypt:ro
depends_on:
- api
restart: always
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
api:
image: registry.example.com/api:${APP_VERSION:-latest}
env_file: .env.production
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
restart: always
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
deploy:
resources:
limits:
cpus: '1.0'
memory: 512M
db:
image: postgres:15-alpine
env_file: .env.production
volumes:
- postgres_data:/var/lib/postgresql/data
restart: always
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres}"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
command: redis-server --requirepass ${REDIS_PASSWORD} --maxmemory 256mb --maxmemory-policy allkeys-lru
volumes:
- redis_data:/data
restart: always
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3
volumes:
postgres_data:
redis_data:
certbot_data:
# Запустить все сервисы
docker compose up -d
# Запустить конкретный сервис
docker compose up -d api
# Следить за логами
docker compose logs -f
docker compose logs -f api
# Остановить сервисы
docker compose down
# Остановить сервисы и удалить тома
docker compose down -v
# Перезапустить сервис
docker compose restart api
# Просмотреть статус сервисов
docker compose ps
# Выполнить команду в сервисе
docker compose exec api bash
# Пересобрать образы
docker compose build --no-cache
docker compose up -d --build
# Проверить конфигурацию
docker compose config
Docker Compose — наиболее практичный способ управления многоконтейнерными приложениями. Он обеспечивает согласованную среду от разработки до production. С override-файлами можно гибко настраивать разные окружения, а с healthcheck и depends_on — безопасно управлять зависимостями сервисов.
'docker compose config' показывает итоговую конфигурацию после применения всех override-файлов и переменных окружения. Полезна для отладки и проверки правильности конфигурации.
'depends_on' по умолчанию ждёт только запуска контейнера, а не его готовности. Используйте 'condition: service_healthy', чтобы ждать прохождения healthcheck. Также рекомендуется добавить логику повторных попыток в приложение.
Docker Compose подходит для развёртывания на одном сервере. Если нужна оркестрация на нескольких серверах, предпочтительнее Kubernetes или Docker Swarm. Docker Compose широко используется в production для приложений малого и среднего масштаба.
Docker Compose автоматически читает файл .env в том же каталоге. Обращайтесь к значениям с синтаксисом '${VARIABLE_NAME}'. Например: 'image: myapp:${APP_VERSION:-latest}'. Используйте ':-' для значений по умолчанию.
Используйте 'expose' вместо 'ports' для масштабируемых сервисов. Expose открывает порт только для внутренней сети. Направляйте внешний трафик через балансировщик нагрузки (nginx, traefik). Так несколько экземпляров могут использовать один и тот же внутренний порт.
'docker compose stop' останавливает контейнеры, но не удаляет их. 'docker compose down' останавливает и удаляет контейнеры. Флаг '-v' также удаляет тома. 'stop' рекомендуется для разработки, 'down' следует использовать осторожно в production.
CI/CD с GitHub Actions: сборка и публикация Docker-образов, развёртывание на сервер по SSH, автотесты, управление секретами и оптимизация workflow.
Ansible по шагам: установка, инвентарь, написание playbook, роли, переменные, зашифрованный vault, ad-hoc команды и автоматизация настройки серверов.
Веб-сервер Caddy: установка, Caddyfile, автоматический SSL от Let's Encrypt, обратный прокси, статические сайты, интеграция PHP-FPM и производительность.