Files
docker/docs/4. Docker Compose - несколько сервисов, сеть, тома.md
T
2026-05-04 12:26:29 +03:00

6.7 KiB
Raw Blame History

Зачем Docker Compose

Когда сервисов несколько (БД, бэкенд, фронт, прокси), писать длинные docker run неудобно. Compose описывает весь стек в одном файле (compose.yaml или docker-compose.yml), поднимает общую сеть и тома, учитывает порядок старта через depends_on и проверки healthcheck.

Команды:

docker compose up -d --build - запустить докер компос в фоне и полностью пересобрать docker compose ps - список контейнеров в докер компос docker compose logs -f api - смотреть в реальном времени логи контейнера api из докер компос docker compose down - остановить контейнере и удалить

Где лежит учебный проект

В репозитории подготовлен полный стек, четыре сервиса:

Путь Содержимое
docker/examples/multi-service/compose.yaml Описание всех сервисов, сетей, томов
docker/examples/multi-service/.env.example Пример переменных окружения для Compose
docker/examples/multi-service/web/ Nginx + статика через COPY
docker/examples/multi-service/api/ Flask + Postgres + загрузка файлов в том
docker/examples/multi-service/proxy/ Входной nginx: / → web, /api/ → api

Скопируйте переменные окружения:

cd docker/examples/multi-service
cp .env.example .env

Запуск:

docker compose up -d --build

Все сервисы подняты

Откройте в браузере адрес с портом из .env (по умолчанию http://127.0.0.1:8080). Главная страница — статика из сервиса web: мини-дашборд с индикаторами прокси, web, API и PostgreSQL (данные приходят с эндпоинта /api/status через прокси), блок заметок (чтение и создание через /api/notes) и простая загрузка файлов в том api_uploads. Всё работает в одной вкладке, без curl — гайд остаётся про Docker и Compose, а проверка стека — через интерфейс.

Скриншот: открытая главная страница с зелёными статусами и списком заметок.

Нам сейчас не интересна логика работы стека, так как не по теме.

Разбор ключевых фрагментов docker-compose.yaml### Имена и сеть

Поле name: multi-service-demo задаёт префикс для имён контейнеров/ресурсов по умолчанию (удобно не конфликтовать с другими проектами).

Сеть backend с драйвером bridge - все перечисленные сервисы в одной L2-сети, видят друг друга по DNS-имени сервиса (db, api, web, proxy).

Зависимости и здоровье

depends_on:
  db:
    condition: service_healthy

Без condition Compose лишь упорядочивает старт, но не ждёт готовности БД. С healthcheck у db сервис api не начнёт считаться поднятым для зависимых, пока Postgres не пройдёт проверку.

expose vs ports

  • ports - публикация на хост (нужно для proxy).
  • expose - документация + открытие порта между контейнерами сети; на сетевой интерфейс хоста не выводится.

Так мы не публикуем Postgres наружу - к БД можно попасть только из контейнеров в той же сети (или если вы явно добавите ports для отладки).

Тома

volumes:
  pgdata:
  api_uploads:

Именованные тома хранятся в области Docker на диске. Пример «скопировать/сохранить файл в Docker» в runtime:

echo hello > /tmp/up.txt
docker cp /tmp/up.txt "$(docker compose ps -q api)":/data/uploads/host-demo.txt
docker compose exec api ls -la /data/uploads

Альтернатива для разработки - bind-mount каталога с хоста в сервис (в учебном файле не включено, чтобы не привязывать пути к вашему $HOME):

services:
  api:
    volumes:
      - ./local_uploads:/data/uploads

Копирование файлов в контейнер в контексте Compose

Способ Когда использовать
COPY в Dockerfile Статика, код, конфиги, которые должны быть в образе на момент деплоя
Именованный / bind том Данные, логи, загрузки пользователей, меняющиеся без пересборки
docker cp Разовая отладка, экстренная подмена файла

Обновление одного сервиса после правки кода

# изменили только api/app.py
docker compose build api
docker compose up -d api

Остановка и очистка

Мягко (тома сохраняются):

docker compose down

Полный сброс демо:

docker compose down -v --rmi local

Документация