← Назад к вопросам

Как на несколько виртуальных машин доставить конфигурацию Docker compose?

2.8 Senior🔥 151 комментариев
#DevOps и инфраструктура

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Доставка Docker Compose на несколько ВМ

Это критическая задача для развёртывания приложений на продакшене. Есть несколько подходов — от простых скриптов до полноценных инструментов оркестрации.

1. Простой подход: SSH и rsync

Для небольшого количества серверов (2-5):

#!/bin/bash
SERVERS=("server1.com" "server2.com" "server3.com")
COMPOSE_FILE="docker-compose.yml"
DEPLOY_DIR="/opt/app"

for server in ${SERVERS[@]}; do
    echo "Deploying to $server..."
    rsync -avz $COMPOSE_FILE root@$server:$DEPLOY_DIR/
    rsync -avz .env.prod root@$server:$DEPLOY_DIR/.env
    ssh root@$server "cd $DEPLOY_DIR && docker-compose pull && docker-compose up -d"
    echo "Deployed to $server"
done

Минусы: ручное управление, нет контроля версий конфигурации, сложно откатывать.

2. Git + SSH (рекомендуется)

Хранить compose файлы в Git репозитории:

#!/bin/bash
SERVERS=("server1.com" "server2.com")
REPO="git@github.com:company/infra.git"
BRANCH="main"
DEPLOY_DIR="/opt/app"

for server in ${SERVERS[@]}; do
    echo "Deploying to $server..."
    ssh root@$server bash << EOSSH
    if [ ! -d $DEPLOY_DIR/.git ]; then
        git clone -b $BRANCH $REPO $DEPLOY_DIR
    else
        cd $DEPLOY_DIR
        git fetch origin
        git checkout $BRANCH
        git pull origin $BRANCH
    fi
    
    cd $DEPLOY_DIR
    docker-compose pull
    docker-compose up -d
EOSSH
done

Преимущества: версионирование, легко откатывать, видна история.

3. Ansible (для масштабирования)

Для управления 10+ серверами:

# ansible/deploy.yml
---
- hosts: webservers
  become: yes
  tasks:
    - name: Create app directory
      file:
        path: /opt/app
        state: directory
        mode: '0755'
    
    - name: Copy docker-compose.yml
      copy:
        src: docker-compose.yml
        dest: /opt/app/
        owner: root
        group: root
        mode: '0644'
    
    - name: Copy .env file
      template:
        src: .env.j2
        dest: /opt/app/.env
        owner: root
        group: root
        mode: '0600'
    
    - name: Pull latest images
      shell: |
        cd /opt/app
        docker-compose pull
    
    - name: Start services
      shell: |
        cd /opt/app
        docker-compose up -d
    
    - name: Check service health
      uri:
        url: http://localhost:8000/health
        status_code: 200
      retries: 3
      delay: 5

Инвентарь:

# ansible/inventory.ini
[webservers]
server1.com
server2.com
server3.com
server4.com

Запуск:

ansible-playbook -i inventory.ini deploy.yml

4. Docker Swarm

Для кластеризации контейнеров:

# Инициализировать Swarm
docker swarm init --advertise-addr 192.168.1.10

# Добавить рабочие узлы
docker swarm join --token SWMTKN-1-xxx 192.168.1.10:2377

# Развернуть сервис
docker stack deploy -c docker-compose.yml myapp

# Проверить статус
docker stack services myapp

# Откатить на предыдущую версию
docker service rollback myapp_web

Преимущества: встроенная интеграция, автоматический перезапуск, rolling updates.

5. Kubernetes

Для production-grade оркестрации:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: web
        image: myapp:latest
        ports:
        - containerPort: 8000
        env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: database_url
kubectl apply -f deployment.yaml
kubectl rollout status deployment/myapp
kubectl rollout undo deployment/myapp  # Откат

6. Полный pipeline с проверками

#!/bin/bash
set -e

echo "[1] Проверка синтаксиса compose файла"
docker-compose config > /dev/null

echo "[2] Сборка образов локально"
docker-compose build

echo "[3] Отправка образов в реестр"
docker-compose push

echo "[4] Развёртывание на серверах"

SERVERS=("prod-server1.com" "prod-server2.com")
for server in ${SERVERS[@]}; do
    echo "Deploying to $server..."
    ssh deploy@$server bash << EODEPLOY
    cd /opt/app
    git pull origin main
    docker-compose pull
    docker-compose up -d
EODEPLOY
    
    curl -f http://$server:8000/health || exit 1
    echo "OK: $server is healthy"
done

echo "SUCCESS: Deploy completed"

Сравнение подходов

МетодСерверовСложностьВерсионированиеОткат
SSH + rsync1-5НизкаяНетРучной
Git + SSH1-10СредняяДаВетка/тег
Ansible10-50СредняяДаИдемпотентность
Swarm50+ВысокаяДаВстроенный
Kubernetes100+ВысокаяДаВстроенный

Лучшие практики

  1. Версионирование конфигов в Git
  2. Секреты отдельно (переменные окружения, vault)
  3. Проверка здоровья после развёртывания
  4. Логирование всех развёртываний
  5. Возможность отката на предыдущую версию
  6. Blue-Green deployment для zero downtime

Итог

  • Для 1-5 серверов: Git + SSH скрипт
  • Для 5-20 серверов: Ansible
  • Для кластеров: Docker Swarm или Kubernetes
  • Всегда: версионирование в Git, тестирование, мониторинг
Как на несколько виртуальных машин доставить конфигурацию Docker compose? | PrepBro