From 00df38bc2a1dbcdc3cdd34c4d6fded6b11c28d29 Mon Sep 17 00:00:00 2001 From: bot-backend Date: Tue, 25 Aug 2026 00:33:55 +0300 Subject: [PATCH] =?UTF-8?q?fix(caddy):=20=D1=80=D0=B0=D0=B7=D0=B4=D0=B5?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=81=D0=B0=D0=B9=D1=82=D0=BE?= =?UTF-8?q?=D0=B2=20=D0=BF=D0=BE=20=D1=85=D0=BE=D1=81=D1=82=D0=B0=D0=BC=20?= =?UTF-8?q?=D0=B4=D0=BE=D1=85=D0=BE=D0=B4=D0=B8=D1=82=20=D0=B4=D0=BE=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BD=D1=82=D0=B5=D0=B9=D0=BD=D0=B5=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #3059 развёл восемь доменов по двум файлам и научил Caddyfile импортировать подмножество через `import caddy/sites/{$CADDY_SITES:*}.caddy`. Но у сервиса caddy в environment стоял только TRADEIN_INTERNAL_AUTH_SECRET, а env_file нет вовсе — переменной в контейнере не было никогда. Плейсхолдер такого вида раскрывает сам Caddy из окружения своего процесса, а не compose при разборе файла. Значит значение с хоста до него не доходило, всегда работал дефолт `*`, и всё разделение существовало только на бумаге. Обнаружилось бы это в день переезда и молча: Caddy на продовом хосте импортировал бы и блок инфраструктурных доменов, пошёл бы выпускать сертификаты для obsidian, errors и git, чей DNS остаётся на другой машине, HTTP-01 падал бы, а Let's Encrypt при этом считает неудачи — пять на домен в час. Дефолт `*` сохранён, поэтому сегодня не меняется ничего: пока переменная не задана ни на одном хосте, импортируются оба файла ровно как раньше. В окне переезда достаточно задать её на каждой машине. Проверено на живом caddy:2 через `caddy adapt` с реальным конфигом, по списку host-матчеров в готовом JSON: переменная не задана — восемь доменов (gendsgn.ru, www, три меры, obsidian, errors, git); CADDY_SITES=apps — пять уезжающих; CADDY_SITES=infra — три остающихся. Refs #3059, #3057 --- docker-compose.prod.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index c8a3d0ef..b0c6e582 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -683,6 +683,20 @@ services: # Пустой дефолт = fail-open (backend не проверяет) → ничего не ломается до # провижининга. Значение задаётся руками в /opt/gendesign/.env на VPS. TRADEIN_INTERNAL_AUTH_SECRET: ${TRADEIN_INTERNAL_AUTH_SECRET:-} + # #3059: какие site-блоки импортирует Caddyfile (`import + # caddy/sites/{$CADDY_SITES:*}.caddy`). Плейсхолдер раскрывает САМ Caddy + # из окружения СВОЕГО контейнера, а не compose из файла окружения хоста — + # поэтому переменную обязательно пробрасывать сюда. Без этой строки + # значение с хоста до Caddy не доходит и всегда работает дефолт `*`, + # то есть оба файла сразу, а разделение хостов молча не срабатывает: + # после переезда (#3057) Caddy на продовом хосте начал бы выпускать + # сертификаты для obsidian/errors/git, чей DNS остаётся на + # инфраструктурном хосте — HTTP-01 падает, а Let's Encrypt считает + # неудачи (5 на домен в час). + # Дефолт `*` = сегодняшнее поведение бит в бит: пока переменная не задана + # ни на одном хосте, импортируются оба файла, как и до этой строки. + # В окне: на продовом хосте CADDY_SITES=apps, на инфраструктурном=infra. + CADDY_SITES: ${CADDY_SITES:-*} volumes: - ./Caddyfile:/etc/caddy/Caddyfile:ro - ./caddy/users.caddy.snippet:/etc/caddy/caddy/users.caddy.snippet:ro