Docker Compose: устройство стека
docker-compose.yml. Порядок деплоя и обязательная проверка по логам — Деплой;
что менять в .env — Переменные окружения. Здесь — сама механика стека:
здоровье сервисов, инициализация, известные слабые места.
Инфраструктурные сервисы
Закреплённые версии: PostgreSQL 16 Alpine, Redis 7 Alpine, Meilisearch 1.12, конкретный релиз
MinIO. PostgreSQL запускается с max_connections=300 для параллельных модулей Medusa (:6).
Пул подключений Medusa к БД расширен до 2–50 соединений, чтобы первый запуск миграций модулей
не зависал (medusa-config.ts:18).
PostgreSQL, Redis, Meilisearch и MinIO хранят данные в именованных persistent volumes. Все
рантайм-сервисы поднимаются с restart: unless-stopped.
Одноразовые init-сервисы
| Сервис | Что делает |
|---|---|
migrate | medusa db:migrate до старта backend |
backend-init | создаёт администратора из ADMIN_EMAIL/ADMIN_PASSWORD, повторный запуск безопасен |
minio-init | создаёт публичный S3-бакет Medusa, разрешает анонимное скачивание файлов (:81) |
cms-db-init | создаёт отдельную БД Strapi после готовности PostgreSQL, имя из STRAPI_DATABASE_NAME (по умолчанию catalog_cms) |
cms-minio-init | создаёт отдельный изолированный бакет и пользователя для CMS со своими реквизитами (:99) |
cms-bootstrap | после готовности CMS создаёт read-токен, начальные опубликованные Homepage/Site settings и сохраняет токен в именованный том |
При отсутствии STRAPI_S3_BUCKET медиа CMS сохраняются в бакет auto-paint-store-cms; при
отсутствии STRAPI_S3_ROOT_PATH — под префиксом media.
MINIO_ROOT_USER/MINIO_ROOT_PASSWORD задают root-доступ самого сервиса MinIO
(docker-compose.yml:69) — этими же реквизитами minio-init и cms-minio-init авторизуются в
MinIO через mc alias set, чтобы создать бакеты и (для CMS) отдельного пользователя.
Сервисы стартуют по зависимостям здоровья/завершения: cms-bootstrap ждёт health-check CMS,
а backend ждёт PostgreSQL, Redis, minio-init, миграции и успешный cms-bootstrap; web
ждёт здоровый backend. Том bootstrap монтируется в backend только для чтения. При ошибке
bootstrap backend намеренно не запускается.
Сеть и порты
| Сервис | Наружу на host | Только внутри docker-сети |
|---|---|---|
| Backend | MEDUSA_PORT (по умолчанию 9000) | — |
| Meilisearch | MEILISEARCH_PORT | — |
Витрина (web) | — | порт 3000, наружу только через reverse proxy (:288) |
| Docs | — | порт 80 через expose, наружу через reverse proxy (:328) |
MEILISEARCH_PORT, MINIO_API_PORT, MINIO_CONSOLE_PORT, MEDUSA_PORT меняют опубликованные
host-порты. Витрина и docs публикацией наружу не занимаются сами — рассчитывают на
reverse proxy перед стеком.
127.0.0.1, не на localhostВнутри контейнера localhost может сначала разрешиться в неподдерживаемый IPv6-адрес — поэтому
проверка здоровья nginx-контейнера docs явно обращается к 127.0.0.1 (:328).
Health-check
Backend, CMS, web и docs получают разные start_period, число повторов и интервалы health-check
(:169).
(*) Health-check витрины принимает больше, чем долженDocker health-check витрины считает здоровым любой HTTP-статус ниже 500, хотя /api/health
должен отвечать ровно 200 (:324) — false positive: web может отвечать 4xx и всё равно
считаться здоровым Docker Compose. Health-check CMS устроен иначе и строже: он использует
response.ok (:289), что фактически означает диапазон 200–299 — 4xx он считает ошибкой
корректно. Не путайте эти два health-check между собой при диагностике: у них разные пороги.
Обязательные секреты при разборе конфигурации
Compose останавливается ещё на разборе конфигурации, если отсутствуют обязательные
production-секреты Strapi, CMS preview и реквизиты CMS S3. STRAPI_READ_TOKEN к ним не
относится: его создаёт cms-bootstrap, а заданное вручную значение лишь переопределяет файл.
(*) Не все ключи шифрования требуются так же строгоПри отсутствии AUTH_MFA_ENCRYPTION_KEY production-compose тихо использует публично известную
резервную строку change-me-local-mfa-encryption-key (:142). Аналогично при отсутствии
MOYSKLAD_ENCRYPTION_KEY — известную строку change-me-local-moysklad-encryption-key (:143).
В отличие от секретов из блока выше, здесь compose не отказывается стартовать — оба значения
обязательно генерировать и задавать вручную перед публикацией наружу, не полагаясь на то, что
их отсутствие остановит запуск.
Если переменные администратора не заданы, backend-init использует резервные admin@test.com
и пароль supersecret (:237) — публичный дефолт из репозитория, не секрет; сменить перед
публикацией обязательно (см. Переменные окружения).
Прочее
- Витрина собирается с
output: "standalone"(apps/web/next.config.ts:6) — минимальный серверный артефакт для контейнера. MEDUSA_ADMIN_ONBOARDING_TYPEуправляет показом первичного мастера настройки админки, по умолчанию пропущен (:122).MEILI_MASTER_KEYодновременно защищает сервер Meilisearch и передаётся backend как API-ключ — единый ключ на оба назначения (:51,157).POSTGRES_DB,POSTGRES_USER,POSTGRES_PASSWORDпереопределяют базу и учётные данные, по умолчаниюmedusa_backend_v2/postgres/postgres— локальные значения, менять перед публикацией.