Nginx 리버스 프록시 환경에서 Jenkins CSS 로딩 오류
🧐 문제 상황
Nginx를 리버스 프록시로 설정하여 http://jenkins.jay-gemini.com 주소로 Jenkins에 접속했을 때, 페이지의 전체적인 레이아웃은 깨지지 않았지만 특정 기능(예: 다크 모드 테마)의 CSS 파일이 로드되지 않는 문제가 발생했습니다.
브라우저의 개발자 도구(F12) 네트워크 탭을 확인했을 때, 아래와 같은 에러가 기록되었습니다.
GET net::ERR_CONNECTION_REFUSED
🔬 원인 분석: 잘못된 리소스 URL
에러 메시지를 보면 문제의 원인을 명확히 알 수 있습니다.
브라우저가 서버의 내부 IP 주소(172.30.1.79)로 CSS 파일을 직접 요청하면서 발생한 문제입니다.
이 현상이 발생하는 과정은 다음과 같습니다.
- 사용자 접속: 웹 브라우저에서 공개 주소인
http://jenkins.jay-gemini.com으로 접속합니다. - Nginx 프록시: Nginx는 이 요청을 받아 내부망에 있는 Jenkins 서버(
http://localhost:8090)로 전달합니다. - Jenkins의 응답: Jenkins는 기본 HTML 페이지를 사용자에게 정상적으로 보냅니다.
- 잘못된 URL 생성: 하지만 Jenkins는 자신이 리버스 프록시 뒤에 있다는 사실을 인지하지 못합니다. 그래서 HTML 내에 포함된 CSS 파일의 경로를 자신의 실제 내부 IP 주소인
http://172.30.1.79:8080으로 생성하여 응답에 포함시킵니다. - 브라우저의 연결 실패: HTML을 받은 브라우저는 CSS를 가져오기 위해
http://172.30.1.79:8080주소로 접속을 시도합니다. 이 주소는 서버 내부에서만 유효한 사설 IP이므로, 외부 인터넷망에 있는 사용자의 브라우저는 당연히 접속할 수 없습니다. 결과적으로ERR_CONNECTION_REFUSED오류가 발생한 것입니다.
💡 해결 과정: 정확한 Host 정보 전달
이 문제의 해결책은 백엔드 서버인 Jenkins가 “자신의 진짜 외부 주소가 무엇인지” 알게 해주는 것입니다. 이는 Nginx의 프록시 헤더 설정을 통해 간단히 해결할 수 있습니다.
SSL 인증서를 적용하는 과정에서 이 헤더 설정을 추가하면서 문제가 해결되었습니다.
수정된 Nginx 설정:
server {
listen 443 ssl;
server_name jenkins.jay-gemini.com;
# SSL 설정...
ssl_certificate /etc/letsencrypt/live/jay-gemini.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/jay-gemini.com/privkey.pem;
location / {
proxy_pass ;
# ★★★ 핵심적인 헤더 설정 ★★★
# 1. 실제 요청된 호스트 주소를 Jenkins에 전달
proxy_set_header Host $host;
# 2. 최초 접속 프로토콜이 https임을 Jenkins에 전달
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
proxy_set_header Host $host;이 한 줄이 결정적인 역할을 합니다. Nginx의$host변수에는 사용자가 실제 요청한 도메인, 즉jenkins.jay-gemini.com이 담겨 있습니다. 이 헤더는 Jenkins에게 **”사용자가 요청한 원래 주소는 이거야”**라고 알려줍니다.proxy_set_header X-Forwarded-Proto $scheme;헤더는 Jenkins가 HTTPS 환경에서 동작 중이라는 사실을 인지시켜 보안 관련 설정을 올바르게 처리하도록 돕습니다.
✅ 결론
Nginx가 Host 헤더를 통해 정확한 공개 도메인 정보를 전달해주자, Jenkins는 더 이상 자신의 내부 IP로 리소스 주소를 생성하지 않게 되었습니다.
대신 https://jenkins.jay-gemini.com/theme-dark/theme.css 와 같이 정상적이고 공개적인 URL을 생성하여 브라우저에 전달했고, 브라우저는 이 주소로 CSS 파일을 성공적으로 가져와 문제를 해결할 수 있었습니다.
핵심 요약: 리버스 프록시 환경에서는 백엔드 애플리케이션이 자신의 공개 주소를 정확히 알 수 있도록 Host 헤더를 올바르게 전달하는 것이 매우 중요합니다.