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
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.
115 lines
5.6 KiB
YAML
115 lines
5.6 KiB
YAML
# Прод-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
|
||
|