Nginx зацикливается после перезапуска контейнера: базовый образ содержит brotli_static в discourse.conf, но модуль не загружается (неизвестная директива)

Резюме
После плановой перезагрузки контейнера (перезагрузка хоста / docker restart) nginx не запускается внутри контейнера app с ошибкой:

nginx: [emerg] unknown directive "brotli_static" in /etc/nginx/conf.d/discourse.conf:172

Это приводит к полному отключению сайта (резервного варианта нет — nginx не привязывается к портам 80/443), пока проблема не будет исправлена вручную.

Окружение

  • Базовый образ: discourse/base:2.0.20260812-0036
  • nginx: 1.26.3-3+deb13u7 (пакет Debian 13/trixie, не скомпилированный вручную)
  • Установлены пакеты libnginx-mod-http-brotli-static/-filter 1.0.0~rc-6, и символические ссылки /etc/nginx/mods-enabled/*.conf (с правильными строками load_module) существуют и указывают на валидные файлы .so.

Причина
В файле /etc/nginx/nginx.conf (принадлежит пакету nginx-common, не изменён) отсутствует директива include /etc/nginx/modules-enabled/*.conf;, поэтому установленные модули Brotli никогда не загружаются — в то время как discourse.conf (генерируемый шаблонами Discourse) по-прежнему содержит строку brotli_static on;, предполагая их наличие.

Почему ошибка не возникает сразу
Конфигурация пересматривается только тогда, когда nginx фактически (пере)запускается. Свежесобранный контейнер может работать нормально в течение дней или недель, пока что-то не перезапустит nginx (перезагрузка хоста, docker restart, OOM и т. д.), после чего он начинает бесшумно зацикливаться на перезапусках (около 1 раза в секунду) без автоматического восстановления.

Временное решение
Добавьте include /etc/nginx/modules-enabled/*.conf; в качестве первой строки в /etc/nginx/nginx.conf (в основном контексте, перед events {}). Подтверждено, что это восстанавливает успешную проверку nginx -t и нормальную работу.

Вопрос
Можно ли в базовом образе либо (a) добавить этот include в его nginx.conf, либо (b) убрать brotli_static/brotli из поставляемого шаблона discourse.conf, если сборка пакета nginx для дистрибутива больше не включает поддержку Brotli по умолчанию?

2 лайка

Исправляю свой отчёт: базовый образ в порядке. Причина была в нашей локальной установке.

Что произошло на самом деле

Локальная cron-задача на нашем хосте копирует устаревшие файлы конфигурации nginx, поддерживаемые вручную, в работающий контейнер. Один из них был создан до добавления строки include /etc/nginx/modules-enabled/*.conf;, а в другом всё ещё задано brotli_static on;. Вместе они вызывают ошибку unknown directive "brotli_static", из-за чего nginx отказывается запускаться.

Почему я ошибся в диагностике

Я проверил /etc/nginx/nginx.conf внутри работающего контейнера и обнаружил, что отсутствует включение modules-enabled. Этот файл уже был перезаписан локально, поэтому работающий контейнер не отражал то, что Discourse на самом деле генерирует. Проверка собранного образа сразу всё проясняет. Включение на месте:

docker create --name check local_discourse/app
docker cp check:/etc/nginx/nginx.conf ./
docker rm check

Почему проблема проявилась с задержкой

Возможно, это полезная часть для других. Задача завершается командой nginx -s reload, и её вывод отбрасывается. Когда конфигурация сломана, перезагрузка происходит тихо, и работающий nginx продолжает обслуживать запросы из уже загруженной конфигурации. Всё выглядит нормально. Поломка становится заметна только при следующем реальном запуске nginx, что в нашем случае произошло при автоматическом обновлении ядра, перезагрузившем хост несколько дней спустя.

Так что, если контейнер Discourse нормально обслуживал трафик, а затем упал при несвязанной перезагрузке, проверьте, не перезаписала ли что-либо его конфигурацию nginx за это время.

Извините за шум и спасибо всем, кто уделил время рассмотрению этого вопроса.

1 лайк