# Caddy-фрагмент: tradein-mvp под gendsgn.ru/trade-in/* # # Этот блок ВКЛЮЧАЕТСЯ в основной gendsgn.ru { ... } блок Caddy # (см. /opt/gendesign/Caddyfile на bot-server). Размещение — ПЕРЕД # универсальным `handle { reverse_proxy frontend:3000 }`, потому что # Caddy матчит handle-блоки сверху вниз. # # DNS — отдельный record НЕ нужен; используется тот же gendsgn.ru. # TLS уже включён в основном блоке (auto через Let's Encrypt). # # URL routes: # gendsgn.ru/trade-in → tradein-frontend:3000 (Next.js basePath=/trade-in) # gendsgn.ru/trade-in/api/v1/* → tradein-backend:8000 (strip префикса /trade-in) handle_path /trade-in/api/* { # handle_path вырезает префикс /trade-in перед прокси → # FastAPI получает /api/v1/... reverse_proxy tradein-backend:8000 { # #654: явный read/write timeout. POST /api/v1/trade-in/estimate делает # цепочку последовательных внешних вызовов (geocode → Overpass → Yandex # valuation → IMV → Cian). In-app time-budget (config.py # estimate_*_timeout_s) суммарно ≈28s worst-case; ставим upstream timeout # ВЫШЕ него (45s), чтобы 503-деградация из приложения доходила до клиента # как 503, а НЕ обрезалась прокси в непрозрачный 502/504. Делает поведение # детерминированным и согласованным с in-app budget. # SHARED-INFRA: этот фрагмент инклудится в основной gendsgn.ru Caddy-блок # на bot-server — требует review devops перед deploy. transport http { read_timeout 45s write_timeout 45s } } } handle /trade-in { redir /trade-in/ permanent } handle /trade-in/* { # Next.js basePath="/trade-in" — фронт сам ждёт префикса в URL reverse_proxy tradein-frontend:3000 }