DevOps & CI/CD

Docker Compose

Инструмент для запуска связки контейнеров одной командой: сервисы, сети и тома описываются в YAML-файле compose.yaml.

Что такое Docker Compose

Docker Compose — инструмент, который описывает многоконтейнерное приложение в одном YAML-файле и поднимает его целиком командой docker compose up. Вместо десятка docker run с длинными списками флагов вы держите конфигурацию в файле рядом с кодом — и она версионируется в Git.

Compose не заменяет Docker, а надстраивается над ним: сборка образов, запуск контейнеров и сами Dockerfile остаются прежними. Compose добавляет то, чего у одиночного контейнера нет: связывание сервисов, порядок запуска, общие сети и тома, единое управление жизненным циклом группы.

Область применения — один хост. Раскидать сервисы по нескольким машинам Compose не умеет: для этого нужен Docker Swarm или Kubernetes.

compose.yaml

Современное имя файла — compose.yaml (старое docker-compose.yml продолжает работать). Ключ version: устарел и больше не нужен.

services:
  api:
    build: .
    ports:
      - "8000:8000"
    environment:
      DATABASE_URL: postgresql://app:secret@db:5432/app
      REDIS_URL: redis://cache:6379
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped

  db:
    image: postgres:16
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: app
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app"]
      interval: 5s
      retries: 5

  cache:
    image: redis:7-alpine
    restart: unless-stopped

volumes:
  pgdata:

Два момента, ради которых Compose и существует:

  1. Имя сервиса — это DNS-имя. Внутри сети Compose api обращается к базе по хосту db, а не по IP-адресу. Compose поднимает общую сеть и резолвит имена сам.
  2. depends_on + condition: service_healthy. Без condition Docker лишь дождётся старта контейнера с PostgreSQL, а не готовности базы принимать соединения — и приложение упадёт на первом запросе. Условие завязано на health check.

Команды

docker compose up -d              # поднять всё в фоне
docker compose up -d --build      # пересобрать образы и поднять
docker compose ps                 # статус сервисов
docker compose logs -f api        # логи одного сервиса
docker compose exec api bash      # войти в контейнер
docker compose restart api        # перезапустить один сервис
docker compose down               # остановить и удалить контейнеры
docker compose down -v            # ... вместе с томами (данные пропадут)
docker compose pull               # обновить образы

Обратите внимание: docker compose (v2, плагин, пишется через пробел) заменил старый docker-compose (v1 на Python, через дефис). Команды почти совпадают, но v1 больше не поддерживается.

Несколько окружений

Compose автоматически подхватывает .env из текущего каталога и умеет накладывать файлы друг на друга — так один базовый конфиг обслуживает и разработку, и production:

docker compose -f compose.yaml -f compose.prod.yaml up -d
# compose.prod.yaml — переопределяет только нужное
services:
  api:
    image: registry.example.com/api:${TAG}
    build: !reset null        # в prod не собираем, берём из registry
    deploy:
      resources:
        limits: {cpus: '2', memory: 2G}

GPU в Compose

Чтобы отдать сервису видеокарту, нужен NVIDIA Container Toolkit на хосте и секция deploy.resources.reservations.devices:

services:
  vllm:
    image: vllm/vllm-openai:latest
    command: --model Qwen/Qwen2.5-7B-Instruct
    ports: ["8000:8000"]
    volumes:
      - ./models:/root/.cache/huggingface
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all        # или device_ids: ['0']
              capabilities: [gpu]

Так на одном GPU-инстансе одной командой поднимается связка «инференс-сервер + веб-интерфейс + Nginx с TLS». Монтирование каталога с весами наружу обязательно — иначе модель будет скачиваться заново при каждом пересоздании контейнера.

Когда Compose перестаёт хватать

Compose живёт на одном хосте: нет автоматического перезапуска на другой машине при отказе железа, нет автомасштабирования, нет rolling update с проверкой готовности. Как только нужен второй сервер — это Swarm (тот же YAML, минимальный переход) или Kubernetes (сложнее, но полноценно).

Связанные термины

  • Docker — платформа, поверх которой работает Compose
  • Dockerfile — как собирается образ для сервиса build:
  • Docker Image — что указывают в image:
  • Docker Swarm — тот же формат на кластере машин
  • Kubernetes — оркестратор для больших установок
  • health check — основа корректного depends_on

Готовы запустить GPU-задачу?

Запустить GPU-сервер