Переезд на Caddy: что ломается на ровном месте
Четыре домена, три бэкенда, один nginx, к которому за пять лет привыкли и перестали читать конфиг. Задача была простая: поставить Caddy, получить автоматические сертификаты и оставить один файл вместо четырёх.
Что сделали до переезда
- Сняли список всех server-блоков и для каждого — список путей, которые уходят на бэкенд, а какие отдаются статикой.
- Прогнали по боевому конфигу
nginx -Tи выписали всеproxy_read_timeout,client_max_body_sizeи*_buffering. - Поставили рядом второй порт и ходили в новый фронтенд напрямую, подменяя Host — так проверка не зависела от DNS.
Ошибка, которая стоила часа
В первом варианте конфига таймауты были выставлены «на глаз»: чтение тела запроса — 30 секунд. Сервис отдавал данные через long-poll, который держится до 40 секунд. Локально, без нагрузочного профиля, всё работало: браузер открывал страницу, обычные запросы проходили.
servers {
timeouts {
read_header 10s
read_body 60s # меньше long-poll — и опросы будут рваться на ровном месте
}
}
Симптом в браузере — не ошибка, а «тихое» поведение: опрос обрывается, клиент переподключается, часть событий теряется, в логах бэкенда пусто. Поймали это только сравнением времени жизни соединения на старом и новом фронтенде:
curl -sS -o /dev/null -w 'connect:%{time_connect} total:%{time_total} code:%{http_code}\n' \
https://example.org/api/v1/events
Три вещи, которые стоит проверить до переключения
| Проверка | Чем грозит пропуск |
|---|---|
Порядок handle и reverse_proxy | Статика отдаётся вместо API, ответ 200 с HTML в теле |
client_max_body_size vs лимит бэкенда | 413 приходит от разных слоёв с разным текстом — клиенты обрабатывают по-разному |
| HSTS на тестовом домене | Заголовок preload на поддомене с самоподписанным окружением ломает доступ на месяцы |
Что получилось
Один файл на 40 строк вместо 260, сертификаты обновляются сами, а в журнале видно только то, что мы сами включили. Автоматического «всё как было» не бывает: nginx-конфиг содержал три костыля, о которых никто не помнил, и два из них действительно были нужны — выяснилось это уже после переключения.
Что бы сделал иначе
- Сразу выписал бы таблицу «путь → бэкенд → таймаут» ещё на этапе чтения старого конфига.
- Не ставил бы HSTS на время миграции: заголовок добавляется в самом конце, когда всё остальное проверено.
- Оставил бы старый фронтендный процесс включённым на другой порт до конца недели — не для трафика, а для сравнения ответов.