Files
chatballs/Caddyfile
T
Andrey 41a4b0dd84 ✨ feat: запуск без .env — всё настраивается в UI, и порталы по дизайну
Первичное требование: поднял докер — прошёл мастер — дальше всё в интерфейсе.
Ни одной переменной окружения задавать не нужно и негде.

Запуск и секреты:
- .env.example удалён, мёртвые переменные вычищены; секреты инстанса
  генерирует одноразовый сервис secrets в именованный том, пароли БД —
  через POSTGRES_*_PASSWORD_FILE;
- Caddy: catch-all :80 и on_demand TLS вместо хостов в конфиге — свежая
  коробка отвечает по IP и по любому домену, до мастера дойти можно;
- адрес установки, SMTP и TURN переехали в настройки (InstanceSettings,
  миграции 0027–0030), внешние ссылки строятся от него;
- deploy/cli больше не читает .env; сборка образов в ghcr через GitHub
  Actions, release.env с digest-пинами;
- куки Secure/__Host- выставляются по факту TLS запроса, а не настройкой.

Порталы (дизайн-базлайн v2, кадры PT1–PT8):
- список, карточка портала, библиотека материалов, редактор статьи и
  настройки — ширины и ритм как в остальных разделах;
- файлы статьи: изображение вставляется в текст своим механизмом, файл
  прикрепляется вложением и выводится на портале списком с иконкой формата;
- ссылки на файлы приводятся к относительным: абсолютный хост резал CSP
  портала и картинка не появлялась;
- «Опубликовать» сверяется с сервером и публикует то, что на экране, а не
  ранее выбранную редакцию;
- колонка «Оценки» в списке статей и блок оценок в редакторе.

Первый запуск: полоса «демо-данные устанавливаются» — установка идёт в
worker, и без неё человек видел пустые разделы без объяснения.

Починен фон: вторичное хранилище стало best-effort — при живых остаточных
S3-ключах повторная загрузка файла падала в 500.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 20:37:48 +03:00

62 lines
2.8 KiB
Caddyfile

# Caddyfile — единый HTTP/HTTPS public boundary Chatballs (ADR-HUB-0028 §gateway).
# Подставляется в release bundle и монтируется в контейнер gateway.
#
# Свежая установка не знает своего домена: человек поднимает докер на сервере и
# открывает её по IP. Поэтому здесь нет блоков с зашитым именем хоста — они бы
# заставили Caddy выпускать сертификат и уводить http на https до того, как
# домен вообще появился. Вместо них: :80 отвечает по http на любом адресе, а
# https обслуживает любой хост, который одобрил ask-эндпоинт (домены порталов и
# домен установки, заданный в UI). Сертификаты выписываются по мере надобности,
# без перезапуска шлюза.
{
# ACME-контакт не задаётся при установке: пока домена нет, нет и выпуска
# сертификатов. Адрес для уведомлений добавляется вместе с доменом в UI.
# Caddy admin API не публикуется наружу (default localhost:2019).
on_demand_tls {
ask http://backend-platform:8000/api/v1/gateway/help-domain/
}
}
(surfaces) {
# Платформенная поверхность живёт на своём домене; пока он не задан,
# матчер намеренно не совпадает ни с чем.
@platform host {$CHATBALLS_PLATFORM_DOMAIN:platform.invalid}
handle @platform {
reverse_proxy backend-platform:8000 {
header_up Host {host}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
}
# Всё остальное — приложение и публичные порталы: маршрутизация внутри
# frontend-контейнера.
handle {
reverse_proxy frontend:80 {
header_up Host {host}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
}
}
# Обычный http на любом адресе: IP сервера, localhost, ещё не подтверждённый
# домен. Редиректа на https здесь нет намеренно — его делает блок ниже, когда
# для хоста реально выписан сертификат.
:80 {
encode gzip zstd
import surfaces
}
# Любой хост, которому ask-эндпоинт разрешил сертификат.
https:// {
encode gzip zstd
tls {
on_demand
}
import surfaces
}