# Caddyfile «Дейла» — PROD edge (compose.prod.yml, Ruling 9/10(3), план Task 14). # # Единственная точка входа наружу: :80/:443. Статика фронта (src/frontend/dist — собирается отдельно: # cd src/frontend && npm run build # ) + reverse_proxy /api/* → core:5080 (HTTP внутри compose-сети). TLS — «tls internal»: Caddy отдаёт # самоподписанный сертификат своего локального CA. Это ПЛЕЙСХОЛДЕР первичного подъёма: # * реальный домен: замените адрес сайта на https://deal.example.com и УБЕРИТЕ «tls internal» — # Caddy выпустит сертификат Let's Encrypt автоматически (нужны публичные 80/443); # * сайт за Cloudflare: вместо этого — origin-сертификат Cloudflare (см. техдок §10); # * доступ по IP без домена: самоподписанный сертификат неизбежен — наружу лучше ничего не открывать, # работать по SSH-туннелю. # # CSP/HSTS сознательно НЕ включены (Ruling 10(3)): CSP для Vue требует nonce-механику (инлайн-стили # карточек, SSE) и включается точечно под реальный фронт; HSTS — только после реального TLS-сертификата. # Заготовки обеих директив — закомментированы ниже в header-блоках. https://deal.example { # Плейсхолдер TLS (см. шапку): реальный домен → удалить эту директиву (Caddy сам выпустит Let's Encrypt). tls internal # API core: весь путь /api/* уходит на core:5080 БЕЗ перезаписи (контракт /api неизменен, api-map §3). # SSE (/api/events), файлы и QR-SVG проходят reverse_proxy потоково (буферизации нет). handle /api/* { header { # Security-заголовки ответов API (Ruling 10(3); CSP/HSTS — заготовки, см. шапку). X-Content-Type-Options "nosniff" X-Frame-Options "DENY" Referrer-Policy "no-referrer" # Strict-Transport-Security "max-age=31536000; includeSubDomains" } reverse_proxy core:5080 } # Статика Vue (src/frontend/dist смонтирована в /srv). SPA-fallback: неизвестный путь отдаёт # index.html — маршруты фронта обрабатывает сам Vue (история браузера). handle { header { X-Content-Type-Options "nosniff" X-Frame-Options "DENY" Referrer-Policy "no-referrer" # Strict-Transport-Security "max-age=31536000; includeSubDomains" # Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-{NONCE}'; style-src 'self' 'unsafe-inline'; connect-src 'self'; img-src 'self' data:; frame-ancestors 'none'; base-uri 'self'" } root * /srv try_files {path} /index.html file_server } }