Материал открыт для чтения

Войдите, чтобы сохранять прогресс и результаты.

Войти
Docker Compose: Многосервисные приложения

Что такое Docker Compose

чтение ~7 минУрок 1 из 16

Что такое Docker Compose

module docker compose Image01

Docker Compose нужен, когда приложение состоит не из одного контейнера, а из нескольких связанных сервисов.

Например, обычное веб-приложение может включать:

  • frontend или nginx — принимает HTTP-запросы;
  • app — выполняет бизнес-логику;
  • db — хранит данные;
  • redis — хранит cache или очередь задач;
  • worker — выполняет фоновые задачи.

Запускать всё это отдельными docker run командами можно, но быстро становится неудобно.

Проблема: несколько контейнеров вручную

Представь стек из базы, backend и nginx:

docker network create demo-net
docker run -d --name db --network demo-net -e POSTGRES_PASSWORD=secret postgres:15-alpine
docker run -d --name app --network demo-net -e DATABASE_URL=postgres://postgres:secret@db:5432/postgres myapp:dev
docker run -d --name nginx --network demo-net -p 8080:80 nginx:alpine

Даже в таком маленьком примере нужно помнить:

  • какую сеть создать;
  • какие переменные окружения передать;
  • какой контейнер должен видеть другой контейнер по имени;
  • какой порт открыть наружу;
  • в каком порядке всё останавливать и пересоздавать.

Если это написано только в README, легко ошибиться: один человек забыл переменную, другой запустил контейнер не в той сети, третий открыл не тот порт.

Docker Compose решает эту проблему: стек описывается в одном YAML-файле и запускается одной командой.

Что делает Compose

Compose описывает не отдельный контейнер, а маленькое приложение целиком.

В compose-файле ты описываешь желаемое состояние:

нужны такие сервисы
им нужны такие images
им нужны такие переменные
им нужны такие ports
они должны быть в такой сети

А Compose уже создаёт контейнеры, подключает их к сети проекта и применяет настройки.

Позже в курсе появится ещё одна важная тема — хранение данных, которые должны переживать пересоздание контейнера. Для этого в Compose используют volumes, но в первой статье достаточно понимать главную идею: Compose помогает описать и запускать несколько связанных сервисов как один стек.

Это важно: compose-файл — не скрипт с командами по шагам. Это декларативное описание. Ты не говоришь “сначала сделай это, потом это”. Ты описываешь, каким должен быть стек, а Compose приводит Docker к этому состоянию.

Минимальный compose-файл

Файл обычно называется compose.yaml или docker-compose.yml.

services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"

Здесь описан один сервис web.

  • services — список сервисов приложения;
  • web — имя сервиса;
  • image: nginx:alpine — какой image запускать;
  • ports: "8080:80" — открыть порт 8080 на хосте и направить его на порт 80 внутри контейнера.

Запуск:

docker compose up -d

После этого nginx будет доступен с хоста:

curl http://localhost:8080

Пример из нескольких сервисов

Теперь пример ближе к реальному приложению:

services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    depends_on:
      - app

  app:
    image: myapp:dev
    environment:
      DATABASE_URL: postgres://postgres:secret@db:5432/postgres
    depends_on:
      - db

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: secret

В этом файле:

  • web публикует порт наружу;
  • app видит базу по имени db;
  • db запускает PostgreSQL с нужной переменной окружения;
  • Compose создаёт общую сеть проекта, поэтому сервисы могут обращаться друг к другу по именам.

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

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

В повседневной работе чаще всего нужны такие команды:

Команда Что делает
docker compose up -d создать и запустить сервисы в фоне
docker compose ps показать состояние сервисов проекта
docker compose logs показать логи всех сервисов
docker compose logs app показать логи одного сервиса
docker compose exec app sh выполнить команду внутри уже запущенного сервиса
docker compose restart app перезапустить один сервис
docker compose down остановить стек и удалить контейнеры проекта

Разбор docker compose up -d: docker compose читает compose-файл в текущей директории, up создаёт недостающие ресурсы и запускает сервисы, -d оставляет их работать в фоне.

Разбор docker compose down: Compose останавливает и удаляет контейнеры проекта и созданную сеть.

Проект Compose

Compose группирует контейнеры и сети в проект. Имя проекта обычно берётся из имени директории.

Если директория называется shop, ресурсы могут получить имена вроде:

shop-web-1
shop-db-1
shop_default

Имя проекта можно задать явно:

docker compose -p demo up -d
docker compose -p demo ps
docker compose -p demo down

Это полезно, когда один и тот же compose-файл нужно запустить несколько раз отдельно: например, для разных тестовых окружений.

exec и run

docker compose exec выполняет команду внутри уже запущенного контейнера сервиса:

docker compose exec db psql -U postgres

Это похоже на docker exec, только вместо имени контейнера указывается имя сервиса из compose-файла.

docker compose run создаёт новый одноразовый контейнер на основе сервиса:

docker compose run --rm app python manage.py migrate

В лабораторных для проверки состояния работающего сервиса чаще нужен exec. Для разовых задач вроде миграций или seed-команд часто используют run --rm.

Диагностика первого уровня

Если стек не стартует, не перезапускай всё наугад. Сначала посмотри состояние:

docker compose ps
docker compose logs --tail=80
docker compose logs app --tail=80

Если один сервис упал, смотри именно его:

docker compose ps app
docker compose logs app --tail=100
docker compose restart app

Compose создаёт обычные Docker containers и networks. Их можно смотреть обычными Docker-командами:

docker ps
docker network ls

Но изменять ресурсы Compose-проекта лучше через docker compose, чтобы состояние Docker не разъехалось с compose-файлом.

Когда запускать up повторно

docker compose up -d можно запускать повторно. Compose сравнит текущие контейнеры с конфигурацией и пересоздаст только то, что изменилось:

docker compose up -d
docker compose ps

Если ты изменил compose-файл, повторный up -d применит изменение. Если изменил только файл в bind mount, пересоздание может быть не нужно: контейнер уже видит файл с хоста.

В следующей статье разберём сам compose-файл как модель: что означает services, где объявлять основные секции, как читать поля сервиса и почему не все порты нужно публиковать наружу.

Материал изучен?

Войдите, чтобы сохранить прогресс и перейти к практической лаборатории.

Войти и продолжить