← К программе курса

Модуль 10 / 18

Docker Compose: модель приложения и окружения

DOCKER

Содержание
01

1. Цели и модель Compose

После модуля вы сможете описать multi-container приложение декларативно, вычислить итоговую конфигурацию, управлять project lifecycle и диагностировать расхождение между YAML и объектами Engine.

  • Compose Specification описывает желаемую модель
  • service — шаблон контейнеров
  • project изолирует имена и lifecycle
  • config показывает вычисленную модель
  • up согласует объекты, down удаляет проектные ресурсы
02

2. Теория: project, service и resource

Compose CLI преобразует compose.yaml в модель project и вызывает Docker API. Это не отдельный orchestrator: контейнеры выполняет тот же Engine. Service задаёт image, command, environment, mounts, networks и другие параметры одного типа workload.

Project name входит в labels и типовые имена ресурсов. Его задают top-level name, -p, COMPOSE_PROJECT_NAME или каталог с определённым приоритетом. Стабильное имя предотвращает случайное управление соседним проектом.

03

3. Теория: вычисление конфигурации

YAML на диске ещё не является effective configuration. Compose объединяет файлы, обрабатывает anchors, profiles и interpolation, нормализует short syntax. docker compose config показывает результат до создания объектов.

Переменные для подстановки берутся из shell и env-файлов по правилам precedence. environment внутри service относится к контейнеру и не тождественен источникам interpolation. Secrets нельзя хранить в committed .env.

04

4. Теория: up, run, exec и down

up создаёт или пересоздаёт изменившиеся services, networks и volumes, затем запускает их. Повторный up должен быть идемпотентным. stop сохраняет контейнеры, start запускает их снова, down удаляет project containers и networks.

exec запускает процесс в существующем service container. run создаёт отдельный one-off container и по умолчанию не публикует service ports. Флаг --rm управляет только этим one-off container.

05

5. Теория: DNS, ports и volumes

Default network создаётся на project, а service names становятся DNS-именами. Между services используют container port; ports нужны лишь для доступа с host или извне.

Named volumes должны быть объявлены. down не удаляет их без -v, потому что данные имеют независимый lifecycle. External resources Compose не создаёт и не должен удалять.

06

6. Теория: profiles, scale и границы Compose

Profiles включают необязательные services: debug tools, migration или maintenance. Service без profile запускается всегда. Явный запуск профилированного service активирует его зависимости, но не превращает profile в production policy.

Scale создаёт несколько контейнеров service, однако fixed container_name и host port мешают масштабированию. Compose одного Engine не обеспечивает multi-host scheduling, rolling update или cluster failover; для этого нужен orchestrator.

07

7. Методические указания

  • Всегда выполняйте config --quiet и просматривайте config
  • Фиксируйте image version или digest
  • Не задавайте container_name без необходимости
  • Разделяйте build-time и runtime variables
  • Привязывайте локальные ports к 127.0.0.1
  • Используйте labels для ownership
  • Не применяйте down -v без проверки данных
  • Запускайте команды из известного project directory
08

8. Лабораторная работа: Compose project

Создайте web и опциональный debug client, исследуйте interpolation и project name.

terminal
mkdir -p /tmp/docker-module-10/html
printf '%s\n' '<!doctype html><html><meta charset="utf-8"><title>Compose lab</title><h1>compose works</h1></html>' > /tmp/docker-module-10/html/index.html
printf '%s\n' 'WEB_PORT=18090' 'APP_ENV=lab' > /tmp/docker-module-10/.env
printf '%s\n' 'name: docker-m10' 'services:' '  web:' '    image: nginx:1.29-alpine' '    ports:' '      - "127.0.0.1:${WEB_PORT:-18090}:80"' '    volumes:' '      - type: bind' '        source: ./html' '        target: /usr/share/nginx/html' '        read_only: true' '    environment:' '      APP_ENV: ${APP_ENV:-development}' '    networks: [frontend]' '    labels:' '      course.module: "10"' '  client:' '    image: alpine:3.21' '    command: ["sh", "-c", "sleep 300"]' '    profiles: [debug]' '    networks: [frontend]' 'networks:' '  frontend:' '    name: docker-m10-frontend' > /tmp/docker-module-10/compose.yaml
cd /tmp/docker-module-10
docker compose version
docker compose config --quiet
docker compose config
docker compose config --services
docker compose config --images
terminal
cd /tmp/docker-module-10
docker compose config --environment
docker compose config --format json | jq '{name,services:(.services | keys),networks:(.networks | keys)}'
WEB_PORT=18091 APP_ENV=override docker compose config --format json | jq '.services.web | {environment,ports}'
docker compose -p docker-m10-alt config --format json | jq '.name'

Запустите profile, проверьте DNS и host publishing, затем наблюдайте reconciliation и scale.

terminal
cd /tmp/docker-module-10
docker compose --profile debug up --detach
docker compose ps
docker compose images
docker compose exec --interactive=false client wget -qO- http://web/
curl --fail --silent --show-error --retry 10 --retry-connrefused --retry-delay 1 http://127.0.0.1:18090/
docker compose logs --no-color --tail 20 web
docker compose top
terminal
cd /tmp/docker-module-10
docker compose --profile debug up --detach --scale client=2
docker compose ps --format json | jq -s 'map({Name,Service,State})'
docker compose --profile debug up --detach
docker compose ps

Критерий: config валиден; client получает страницу по имени web; loopback port отвечает; повторный up сохраняет желаемое состояние.

09

9. Диагностика Compose

Идите от effective model к project labels и фактическим объектам. Не начинайте с удаления проекта.

terminal
cd /tmp/docker-module-10
docker compose config --quiet
docker compose ps --all
docker compose logs --no-color --timestamps --tail 50
docker compose events --json --since 10m --until 0s 2>/dev/null | tail -20 || true
docker network inspect docker-m10-frontend
docker inspect docker-m10-web-1 --format '{{json .Config.Labels}}' | jq
  • config: interpolation, merge и profiles
  • ps --all: exited и restarting containers
  • logs: stderr/stdout каждого service
  • inspect labels: project, service и config hash
  • network/volume inspect: membership и ownership
  • events: последовательность create/start/die
10

10. Контроль и cleanup

  • Чем service отличается от container?
  • Как определяется project name?
  • Почему config важнее чтения одного YAML?
  • Чем run отличается от exec?
  • Что удаляет down?
  • Почему container_name мешает scale?
  • Зачем profiles?
  • Где заканчиваются возможности Compose?
terminal
cd /tmp/docker-module-10
docker compose --profile debug down --remove-orphans
cd /
rm -f /tmp/docker-module-10/compose.yaml /tmp/docker-module-10/.env /tmp/docker-module-10/html/index.html
rmdir /tmp/docker-module-10/html /tmp/docker-module-10
docker ps -a --filter label=com.docker.compose.project=docker-m10
docker network ls --filter name=docker-m10

Модуль освоен, если вы предсказываете effective configuration, безопасно управляете project lifecycle и находите объект по Compose labels.