VDS · Docker и контейнеры

Docker Compose: несколько служб одной командой

Как описать связку из приложения, базы и веб-сервера в одном файле, поднять её одной командой и обновлять без ручной пересборки.

Обновлено 23 августа 2026 г.

Один сервис можно запустить длинной строкой docker run. Два сервиса, которым нужно видеть друг друга, — уже нет: вы забудете параметры на следующий день. Compose переносит всё описание в файл, который можно читать, править и хранить в репозитории.

Минимальный пример

Каталог /opt/myapp, в нём compose.yaml:

services:
  db:
    image: postgres:17
    restart: unless-stopped
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_DB: app
    volumes:
      - db-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      retries: 5

  app:
    image: ghcr.io/example/app:1.4.2
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
    environment:
      DATABASE_URL: postgres://postgres:${DB_PASSWORD}@db:5432/app
    ports:
      - "127.0.0.1:8080:8080"

volumes:
  db-data:

Рядом файл .env:

DB_PASSWORD=длинный-случайный-пароль
chmod 600 .env
docker compose up -d
docker compose ps
docker compose logs -f app

Что здесь важно

  • Имена вместо адресов. Приложение обращается к базе по имени db — Compose создаёт общую сеть, где имена служб разрешаются автоматически. Порт базы наружу публиковать не нужно, и не надо.
  • restart: unless-stopped. Без него после перезагрузки машины ничего не поднимется.
  • depends_on с проверкой здоровья. Обычный depends_on ждёт только запуска контейнера, а не готовности базы принимать соединения. Приложение стартует раньше и падает.
  • Точные версии образов. postgres:17, а не postgres:latest. С latest очередной pull однажды поднимет мажорную версию, которая не откроет старые данные.
  • Публикация на 127.0.0.1. Наружу порт выставляйте только через веб-сервер с сертификатом.

Повседневные команды

docker compose up -d          # поднять или применить изменения
docker compose down           # остановить и удалить контейнеры (тома целы)
docker compose down -v        # ...и удалить тома тоже
docker compose restart app    # перезапустить одну службу
docker compose exec app sh    # зайти внутрь
docker compose pull && docker compose up -d   # обновить образы
docker compose config         # показать итоговый файл с подстановками

docker compose config — лучший способ проверить файл до запуска: он покажет, во что развернулись переменные и не потерялся ли отступ.

docker compose down -v удаляет тома вместе с базой данных. Это необратимо. Перед любой операцией с -v убедитесь, что копия есть, — см. резервные копии.

Файлы окружений

Один и тот же стек для проверки и для боевой работы удобно разводить наложением:

docker compose -f compose.yaml -f compose.prod.yaml up -d

Во втором файле переопределяются только отличия: лимиты памяти, публикуемые порты, уровень журнала.

Частые ошибки

  • Секреты в compose.yaml, который лежит в репозитории. Держите их в .env с правами 600 и не коммитьте.
  • Смешение docker-compose и docker compose. Старая версия v1 не понимает часть синтаксиса и хранит проекты под другими именами. Ставьте плагин — см. установку Docker.
  • Данные в контейнере, а не в томе. После docker compose down они исчезнут. См. тома.
  • Нет ограничений памяти. Один сервис съедает всю память машины, ядро убивает соседние. См. ограничения ресурсов.