컨테이너 재시작 후 Nginx가 크래시 루프에 빠짐: 기본 이미지에서 discourse.conf에 brotli_static이 포함되어 있지만 모듈이 로드되지 않아 unknown directive 오류 발생

요약
루틴 컨테이너 재시작(호스트 재부팅 / docker restart) 후, app 컨테이너 내에서 nginx가 시작되지 않으며 다음 오류가 발생합니다:

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 등)가 발생하기까지 며칠에서 몇 주 동안 정상적으로 실행될 수 있습니다. 이 시점에 nginx는 자동 복구 없이 조용히 크래시 루프(~1초/1회)에 진입합니다.

우회 방법
/etc/nginx/nginx.conf의 첫 번째 줄(events {} 이전, 메인 컨텍스트)에 include /etc/nginx/modules-enabled/*.conf;를 추가하십시오. 이를 통해 nginx -t 성공 및 정상 작동이 복구된 것을 확인했습니다.

요청 사항
베이스 이미지가 다음 중 하나를 수행할 수 있을까요? (a) nginx.conf에 해당 include를 추가하거나, (b) 디스트로 nginx 패키지 빌드가 더 이상 기본적으로 Brotli 지원을 번들링하지 않는 경우, 포함된 discourse.conf 템플릿에서 brotli_static/brotli를 제거하는 것입니다.

2개의 좋아요

제 보고서를 수정합니다: 베이스 이미지에 문제는 없습니다. 원인은 저희 설치 환경에 있었습니다.

실제로 일어난 일

저희 호스트의 로컬 cron 작업이 오래되고 수동으로 관리되던 nginx 설정 파일을 실행 중인 컨테이너로 복사하고 있었습니다. 그중 하나는 include /etc/nginx/modules-enabled/*.conf;보다 이전 버전의 설정이었고, 다른 하나는 여전히 brotli_static on;를 설정하고 있었습니다. 이 두 가지가 결합되어 unknown directive "brotli_static" 오류를 발생시켰고, nginx가 시작되지 않았습니다.

잘못 진단했던 이유

실행 중인 컨테이너 내부의 /etc/nginx/nginx.conf를 확인했을 때 modules-enabled include가 누락되어 있었습니다. 해당 파일은 이미 로컬에서 덮어쓰기되어 있었기 때문에, 실행 중인 컨테이너는 Discourse가 실제로 생성하는 내용을 반영하지 못하고 있었습니다. 대신 빌드된 이미지를 확인하면 명확합니다. include가 존재합니다:

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

지연되어 발현된 이유

이 부분이 다른 분들에게 유용할 수 있습니다. 해당 작업은 nginx -s reload로 끝나며 그 출력은 버려집니다. 설정이 손상되면 reload가 조용히 실패하고, 실행 중인 nginx는 이미 로드된 설정으로 서비스를 계속 제공합니다. 모든 것이 정상적으로 보입니다. 손상은 다음 실제 nginx 시작 시에만 드러나는데, 저희의 경우 며칠 후 비자동(kernel) 업그레이드로 호스트가 재부팅되면서였습니다.

따라서 Discourse 컨테이너가 정상적으로 트래픽을 처리하다가 나중에 무관한 재부팅으로 죽는 경우, 그 사이에 nginx 설정이 무엇에 의해 덮어쓰기되었는지 확인해 보세요.

혼동을 드려 죄송하며, 이 문제를 살펴봐 주신 분들께 감사드립니다.

1개의 좋아요