Мой предыдущий коммит попал в файлы через шелл-heredoc, который съел
экранирование: вместо двух символов backslash+n в литерал уехал НАСТОЯЩИЙ
перевод строки, и обе строки стали незакрытыми (TS1002 Unterminated
string literal). Именно поэтому frontend-checks остался красным, хотя сама
логика чтения объединённого конфига верна.
Refs #3059
CI поймал настоящую связь, которую разделение site-блоков порвало: два
фронтовых теста читают Caddyfile как ИСТОЧНИК ПРАВДЫ о публичном
периметре, а не дублируют список путей.
public-perimeter.test.ts — ищет блок meraocenka.ru, сверяет, что каждый
маршрут из PUBLIC_ROUTES раздаётся, и что у
каждой страницы есть 301 с длинного адреса
RouteGuard.publicPaths.ts — вытаскивает матчер @meraPages и сверяет с
списком публичных путей в гварде
Оба комментария прямо объясняют, зачем так: списки уже расходились дважды
(15.08 и 16.08), причём страница в обоих случаях отдавала 200 и ломалась
только после гидратации — ни один тест по коду ответа этого не видел.
После переноса site-блоков в caddy/sites/*.caddy корневой файл этих блоков
не содержит, и проверки стали бы пустыми. Тесты честно упали на своих же
страховках («блок не найден — иначе проверки ниже пустые», «не нашли
матчер @meraPages — проверка стала бы пустой»), а не тихо позеленели.
Теперь оба читают эффективный конфиг: корневой Caddyfile + все
caddy/sites/*.caddy. Все файлы берутся намеренно — `import
caddy/sites/{$CADDY_SITES:*}` без переменной раскрывается в звёздочку,
то есть это и есть конфиг по умолчанию.
Проверено симуляцией ровно тех утверждений, на которых падал CI: срез
между meraocenka.ru и merahome.ru = 10 458 символов (тест ждёт >500),
матчер @meraPages найден, в нём 5 путей. Запустить vitest локально не
вышло — фронтовые зависимости не установлены (node_modules/.bin пуст),
так что окончательная проверка за CI.
Refs #3059
Корневой Caddyfile содержал все восемь доменов. Деплой синхронизирует
рабочее дерево с origin/main и перечитывает конфиг, поэтому на Selectel
приехал бы файл целиком — и Caddy начал бы выпускать сертификаты для
obsidian/errors/git, чей DNS указывает на Beget. ACME падал бы на HTTP-01,
с риском упереться в rate limit Let's Encrypt.
Вторая, более тяжёлая сторона той же проблемы: сейчас ЭТОТ Caddy —
единственный публичный вход и для тех трёх доменов тоже. Он уезжает, а
Forgejo, GlitchTip и CouchDB остаются. Без разделения они отдавали бы
502, оставаясь живыми. Теперь на Beget остаётся Caddy с CADDY_SITES=infra.
caddy/sites/apps.caddy gendsgn.ru, www, meraocenka, merahome, meraotsenka
caddy/sites/infra.caddy obsidian, errors, git
Корневой файл ужался с 522 строк до 96: глобальные опции, snippet'ы,
блок :80 и два import. Site-блоки перенесены дословно, вместе с
комментариями.
Проверено caddy adapt в трёх режимах:
без переменной -> 8 доменов (текущее поведение Beget, не меняется)
CADDY_SITES=apps -> 5
CADDY_SITES=infra -> 3
Две правки, найденные валидацией: синтаксис дефолта у Caddy {$VAR:default},
а не {$VAR:-default}; путь к users.caddy.snippet из подкаталога стал
../users.caddy.snippet — import резолвится относительно импортирующего файла.
Refs #3059, #3057, #2989