food-market/deploy/docker-compose.yml
nns c4a59d7bf2
Some checks failed
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker API / Build + push API (push) Waiting to run
Docker API / Deploy API on stage (push) Blocked by required conditions
Docker Public / Build + push Public (test + latest) (push) Has been cancelled
Docker Web / Build + push Web (push) Has been cancelled
Docker Public / Deploy :test → test.food-market.kz (push) Has been cancelled
Docker Web / Deploy Web on stage (push) Has been cancelled
docs(prod): репа догоняет новую раскладку postgres на prod-vm
05.10.2026 общий postgres-инстанс с чужими боевыми базами (sklad, purchase,
calcman, calcman_staging, makesales + мусорная старая food_market) вынесен
из compose прода food-market в отдельный compose-проект shared-postgres
(контейнер shared-postgres, порт 5434, том food-market-postgres-data external).
Прод food-market поднимается в собственный контейнер food-market-prod-postgres
(порт 5437, том food-market-prod-postgres-data). Простой при разделении — 12с,
соседи живы. См. docs/shared-postgres-followup-progress.md.

Этот коммит синхронизирует репозиторий, чтобы следующий деплой из main не
воскресил старую раскладку:

- deploy/docker-compose.yml: container_name/port/volume приведены к прод-файлу
  (food-market-prod-postgres, 127.0.0.1:5437, food-market-prod-postgres-data).
- deploy/shared-postgres/ (новое): документационная копия соседнего compose'а,
  с явной пометкой «food-market им не управляет».
- deploy/food-market-backup.sh / anonymize-prod.sh / db-schema-diff.sh:
  defaults FM_PG_CONTAINER / FM_PROD_CONT = food-market-prod-postgres.
- docs/RUNBOOK.md: новый раздел «Postgres на prod-vm» с таблицей трёх
  инстансов и явным запретом трогать shared-postgres из наших скриптов.
- docs/backup-restore.md: контейнер в таблице и примерах — новый.

Guards (не в репе — живут в ~/deploy-stage.sh и ~/quality-watchdog.sh)
расширены симметрично: стенду запрещены shared-postgres, food-market-prod-
postgres[-data], 5434/5437; проду — food-market-postgres-data (чужие данные).
Проверка: docker compose config/ps на prod-vm shared-postgres не упоминают,
grep по репе — ни один скрипт не делает docker exec в shared-postgres.
2026-10-06 00:35:54 +05:00

115 lines
5.6 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Прод-compose food-market.
#
# ВАЖНО (2026-10-05): у food-market свой postgres прода — контейнер
# `food-market-prod-postgres`, том `food-market-prod-postgres-data`, порт
# `127.0.0.1:5437`. На prod-vm параллельно существует отдельный compose-проект
# `shared-postgres` (~/shared-postgres/docker-compose.yml, порт 5434, том
# `food-market-postgres-data` *external*) с ЧУЖИМИ боевыми базами (sklad,
# purchase, calcman, calcman_staging, makesales). Он food-market НЕ принадлежит
# и в этот compose возвращаться НЕ должен. См. docs/shared-postgres-followup-progress.md.
#
# Guards в ~/deploy-stage.sh и ~/quality-watchdog.sh падают, если здесь появится
# `shared-postgres`, `food-market-postgres-data`, порт `5434` или старое имя
# контейнера `food-market-postgres`.
services:
postgres:
image: ${REGISTRY:-127.0.0.1:5001}/mirror/postgres:16-alpine
container_name: food-market-prod-postgres
restart: unless-stopped
environment:
POSTGRES_DB: food_market
POSTGRES_USER: food_market
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-food_market_dev}
PGDATA: /var/lib/postgresql/data/pgdata
# prod-vm занят: 5432 — host postgres, 5434 — shared-postgres (чужой),
# 5435 — stage-postgres, 5436 — food-market-server-postgres (сосед).
# Нам остаётся 5437.
ports:
- "127.0.0.1:5437:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U food_market -d food_market"]
interval: 10s
timeout: 5s
retries: 5
api:
image: ${REGISTRY:-127.0.0.1:5001}/food-market-api:${API_TAG:-latest}
container_name: food-market-api
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
environment:
ASPNETCORE_ENVIRONMENT: Production
ConnectionStrings__Default: Host=postgres;Port=5432;Database=food_market;Username=food_market;Password=${POSTGRES_PASSWORD:-food_market_dev}
# Публичный issuer токенов — обязателен за прокси, иначе берётся из запроса
# (или дефолт localhost из appsettings, что неверно для прод).
OpenIddict__Issuer: ${OPENIDDICT_ISSUER:-https://admin.food-market.kz/}
# Пароль PFX-сертификатов OpenIddict (пусто = сертификаты без пароля).
OpenIddict__CertPassword: ${OPENIDDICT_CERT_PASSWORD:-}
# Sprint 13: rate-limit на signup. На stage'е переопределяется в
# .env'е через RATE_SIGNUP_HOUR / RATE_SIGNUP_DAY для прохождения
# e2e/smoke; в prod'е оставляем дефолты 3/час, 10/сутки.
RateLimiting__SignupPerIpPerHour: ${RATE_SIGNUP_HOUR:-3}
RateLimiting__SignupPerIpPerDay: ${RATE_SIGNUP_DAY:-10}
# Sprint 30: «быстрый вход» на тестовом стенде. По умолчанию выключено.
# На stage включается через QUICK_LOGIN_ENABLED=true в .env.
# QUICK_LOGIN_MASTER_PASSWORD задаётся секрет-паролем стенда (значение
# хранится вне репозитория — на dev-vm в ~/.fm-watchdog/stage-shared-
# password). Если переменная пустая — master-password-режим отключён
# (IsMasterPassword отбивает пустую строку). SPA отправляет публичный
# sentinel '__QUICK_LOGIN_PWLESS__' — реальный пароль в JS не попадает.
# Code имеет safety-override: даже с Enabled=true, если OpenIddict__
# Issuer смотрит на admin.food-market.kz — быстрый вход принудительно
# выключен (см. QuickLoginOptions.EffectivelyEnabled).
QuickLogin__Enabled: ${QUICK_LOGIN_ENABLED:-false}
QuickLogin__MasterPassword: ${QUICK_LOGIN_MASTER_PASSWORD:-}
# Host port mapping: pick free ports on existing stage server (80/443 taken by
# legacy nginx, 5000/5002/5005 taken by legacy .NET apps).
ports:
- "8080:8080" # api
healthcheck:
# Готовность = БД отвечает + миграции применены (см. /health/ready).
test: ["CMD-SHELL", "curl -fsS http://localhost:8080/health/ready || exit 1"]
interval: 30s
timeout: 5s
retries: 5
start_period: 30s
volumes:
- api-data:/app/App_Data
- api-logs:/app/logs
- /opt/food-market-data/uploads:/app/uploads
web:
image: ${REGISTRY:-127.0.0.1:5001}/food-market-web:${WEB_TAG:-latest}
container_name: food-market-web
restart: unless-stopped
depends_on:
api:
condition: service_healthy
ports:
- "8081:80" # web SPA, not on 80 (legacy nginx holds it)
public:
image: ${REGISTRY:-127.0.0.1:5001}/food-market-public:${PUBLIC_TAG:-latest}
container_name: food-market-public
restart: unless-stopped
ports:
- "8082:80" # marketing astro static
volumes:
postgres-data:
# ВАЖНО: НЕ `food-market-postgres-data` — тот том принадлежит отдельному
# проекту shared-postgres (чужие боевые базы). См. docs/shared-postgres-followup-progress.md.
name: food-market-prod-postgres-data
api-data:
name: food-market-api-data
api-logs:
name: food-market-api-logs