#!/usr/bin/env bash set -euo pipefail echo "[entrypoint] Применение миграций…" alembic upgrade head echo "[entrypoint] Бутстрап справочников и администратора…" python -m app.bootstrap echo "[entrypoint] Запуск сервера…" # --proxy-headers + доверие к X-Forwarded-* от реверс-прокси (Caddy на VPS): # чтобы приложение знало, что снаружи запрос пришёл по HTTPS и кто реальный клиент. # # forwarded-allow-ips НЕ "*" (#58): при "*" uvicorn брал ЛЕВОЕ значение X-Forwarded-For, # и клиент мог подставить произвольный IP (снятие throttle, порча аудита). Доверяем только # апстримам из приватной сети compose (туннель к Caddy ходит на app:8000) и loopback # (healthcheck) — тогда uvicorn сканирует XFF справа и берёт первый недоверенный адрес, # т.е. реальный, добавленный Caddy. Портов на хост нет, снаружи к :8000 никто не ходит. # Переопределяемо через FORWARDED_ALLOW_IPS, если сеть отличается. # --timeout-graceful-shutdown: SSE-потоки /api/events сами не закрываются, и без лимита # остановка ждала бы их до SIGKILL по stop_grace_period (30 с) — без lifespan-shutdown. FORWARDED_ALLOW_IPS="${FORWARDED_ALLOW_IPS:-127.0.0.1,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16}" exec uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 1 \ --proxy-headers --forwarded-allow-ips="$FORWARDED_ALLOW_IPS" --timeout-graceful-shutdown 10