Введение
Docker Swarm — встроенная оркестрация контейнеров в Docker, которая предлагает простоту использования и отличную интеграцию с Docker Compose. В отличие от Kubernetes, Docker Swarm требует минимальной настройки и идеально подходит для малых и средних проектов.
В ExtTeam мы используем Docker Swarm для деплоя Nuxt приложений в production. Это позволяет нам обеспечить высокую доступность, zero-downtime deployments и простое масштабирование.
Почему Docker Swarm, а не Kubernetes?
Docker Swarm vs Kubernetes — вечный вопрос. Вот наши критерии выбора:
- Kubernetes: для крупных проектов с 50+ микросервисами, сложной сетевой топологией
- Docker Swarm: для средних проектов (5-20 сервисов), быстрый старт, простота
- Docker Swarm интегрирован в Docker, не требует дополнительных инструментов
- Kubernetes требует существенных знаний и времени на настройку
- Docker Swarm использует привычный docker-compose.yml синтаксис
Для большинства Nuxt проектов Docker Swarm — оптимальный выбор.
Подготовка инфраструктуры
Минимальные требования для production swarm:
- 1 manager node (минимум 2GB RAM, 2 CPU)
- 2-3 worker nodes для high availability
- Docker 24.0+ на всех нодах
- Открытые порты: 2377 (cluster management), 7946 (node communication), 4789 (overlay network)
Инициализация swarm на manager node:
# На manager node
docker swarm init --advertise-addr <MANAGER-IP>
# Получить команду для добавления worker nodes
docker swarm join-token workerDocker Compose для production
Пример production compose файла для Nuxt + Directus:
version: '3.8'
services:
traefik:
image: traefik:3.4
ports:
- "80:80"
- "443:443"
deploy:
replicas: 1
placement:
constraints:
- node.role == manager
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- traefik-certificates:/certificates
command:
- --providers.docker.swarmMode=true
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --certificatesresolvers.letsencrypt.acme.email=admin@example.com
- --certificatesresolvers.letsencrypt.acme.storage=/certificates/acme.json
nuxt:
image: registry.example.com/nuxt:latest
deploy:
replicas: 2
update_config:
parallelism: 1
delay: 10s
rollback_config:
parallelism: 1
labels:
- traefik.enable=true
- traefik.http.routers.nuxt.rule=Host(`example.com`)
- traefik.http.services.nuxt.loadbalancer.server.port=3000
environment:
- NODE_ENV=production
secrets:
- nuxt_env
directus:
image: directus/directus:latest
deploy:
replicas: 1
secrets:
- directus_key
- directus_secret
- db_password
secrets:
nuxt_env:
external: true
directus_key:
external: true
directus_secret:
external: true
volumes:
traefik-certificates:Secrets Management с SOPS + Age
Для безопасного хранения secrets используем SOPS с Age шифрованием:
# Установка SOPS и Age
brew install sops age # macOS
apt install sops age # Linux
# Генерация ключа
age-keygen -o key.txt
# Конфигурация .sops.yaml
cat << EOF > .sops.yaml
creation_rules:
- path_regex: \.env.*\.prod$
age: age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
EOF
# Шифрование .env файла
sops -e .env.prod > .env.prod.encrypted
# Дешифрование в CI/CD
export SOPS_AGE_KEY=$(cat key.txt)
sops -d .env.prod.encrypted > .env.prodTraefik как reverse proxy
Traefik автоматически обнаруживает сервисы в Docker Swarm и настраивает маршрутизацию:
- Автоматическое получение Let's Encrypt сертификатов
- Load balancing между репликами
- HTTP to HTTPS redirect
- WebSocket поддержка
- Middleware для rate limiting, CORS, auth
# Конфигурация Traefik labels для сервиса
deploy:
labels:
- traefik.enable=true
- traefik.http.routers.app.rule=Host(`example.com`)
- traefik.http.routers.app.entrypoints=websecure
- traefik.http.routers.app.tls.certresolver=letsencrypt
- traefik.http.services.app.loadbalancer.server.port=3000
- traefik.http.middlewares.redirect-https.redirectscheme.scheme=httpsZero-downtime deployment
Docker Swarm поддерживает rolling updates из коробки:
deploy:
replicas: 2
update_config:
parallelism: 1 # Обновлять по 1 контейнеру
delay: 10s # Задержка между обновлениями
failure_action: rollback # Откат при ошибке
monitor: 30s # Время мониторинга после обновления
order: start-first # Сначала запустить новый, потом остановить старый
rollback_config:
parallelism: 1
delay: 5sОбновление сервиса:
# Обновить образ сервиса
docker service update --image registry.example.com/nuxt:v2.0 stack_nuxt
# Откатить к предыдущей версии
docker service rollback stack_nuxtМониторинг и логирование
Для production важен мониторинг состояния сервисов:
# Статус сервисов
docker service ls
# Логи конкретного сервиса
docker service logs -f stack_nuxt
# Масштабирование
docker service scale stack_nuxt=4
# Health checks
docker service ps stack_nuxtHealth check в compose файле:
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3000/api/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40sBackup и recovery
Критически важные данные должны регулярно бэкапиться:
# Бэкап PostgreSQL
docker exec postgres pg_dump -U user database > backup.sql
# Бэкап volumes
docker run --rm -v stack_data:/data -v $(pwd):/backup \
alpine tar czf /backup/data-backup.tar.gz /data
# Восстановление
docker exec -i postgres psql -U user database < backup.sqlBest Practices
- Используйте минимум 2 replicas для критичных сервисов
- Настройте health checks для всех сервисов
- Храните secrets в Docker secrets, а не в переменных окружения
- Используйте constraint для критичных сервисов (например, DB только на manager node)
- Регулярно обновляйте Docker и базовые образы
- Настройте автоматические бэкапы
- Используйте overlay networks для изоляции сервисов
- Мониторьте ресурсы (CPU, RAM, disk) на всех нодах
Заключение
Docker Swarm предоставляет простой и эффективный способ развернуть Nuxt приложения в production. Zero-downtime deployments, автоматическое масштабирование и встроенный load balancing делают его отличным выбором для большинства проектов.
В ExtTeam мы успешно используем Docker Swarm для production deployment всех наших Nuxt проектов, обслуживая миллионы запросов ежемесячно с uptime 99.9%.
