Урок 07 · Compose

WMS-контур через Compose

Опишите frontend, DB и одноразовый Playwright runner как одну application model и запускайте тесты только после readiness.

Время: 25 минутРезультат: управляемый stackИнтервью: running ≠ ready

Найдите race condition

depends_on: [db] запускает DB раньше API. Гарантирует ли это, что DB уже принимает connections? Объясните.

Application model

Compose file описывает services, networks и volumes. Service — желаемая конфигурация container, а project группирует созданные ресурсы. Внутри default network services доступны по своим именам.

name: wms-test

services:
  frontend:
    image: nginx:alpine
    ports:
      - "127.0.0.1:8080:80"
    healthcheck:
      test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1/"]
      interval: 5s
      timeout: 2s
      retries: 10

  db:
    image: postgres:17-alpine
    environment:
      POSTGRES_DB: wms
      POSTGRES_USER: wms
      POSTGRES_PASSWORD: local-test-only
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U wms -d wms"]
      interval: 5s
      timeout: 3s
      retries: 10
    volumes:
      - db-data:/var/lib/postgresql/data

  tests:
    image: wms-playwright:dev
    profiles: ["test"]
    environment:
      BASE_URL: http://frontend:80
      DATABASE_URL: postgres://wms:local-test-only@db:5432/wms
    depends_on:
      frontend:
        condition: service_healthy
      db:
        condition: service_healthy
    volumes:
      - ./test-results:/work/test-results
      - ./playwright-report:/work/playwright-report

volumes:
  db-data:

Пароль здесь допустим только как явно локальное учебное значение. Реальные secrets не коммитятся в Compose file.

Running не означает ready

Container получает status running сразу после старта process. Приложение ещё может выполнять migrations, прогревать cache или открывать listen socket. healthcheck определяет проверяемый признак готовности, а condition: service_healthy связывает с ним dependent service.

Healthcheck проверяет контрактПроверка process existence слабее проверки реальной зависимости. Для DB используйте запрос готовности, для HTTP — endpoint, который отражает возможность обслуживать нужный сценарий.

Управление контуром

# Проверить итоговую конфигурацию и подстановки
docker compose config

# Поднять долгоживущие зависимости и дождаться health
docker compose up --detach --wait frontend db
docker compose ps

# Запустить одноразовый test container
docker compose --profile test run --rm tests

# Собрать факты при сбое
docker compose ps --all
docker compose logs --timestamps frontend db

# Удалить containers/network, сохранить named volume
docker compose down

# Полный reset учебной DB
docker compose down --volumes

run --rm tests создаёт one-off container из конфигурации service. Это естественная модель для CI test job: зависимости живут, test runner выполняется один раз, artifacts остаются в workspace.

Разбор сбоя в WMS-сценарии

Тест авторизации падает с connection refused. Порядок анализа:

  1. compose ps: health/status каждого service.
  2. compose logs: migrations, listen address, crash.
  3. Из tests container проверить http://frontend:80, а не host port.
  4. Сверить environment после interpolation через compose config, не публикуя secrets в лог.
  5. Отделить startup race от функционального дефекта и flaky test.

«Compose для меня — декларативная модель локального/CI-контура. Services общаются по DNS-именам внутри общей сети. Я различаю process running и application ready: добавляю meaningful healthchecks и запускаю test runner после service_healthy. Сам runner делаю one-off через compose run --rm, а reports выношу bind mount в CI workspace».

Проверка понимания

1. Что гарантирует короткий depends_on?

2. Как запустить test runner один раз?

3. Что делает compose down -v?

Первичные источники

Попросите преподавателя проверить healthcheck: он должен отражать готовность именно вашего dependency contract.