Nginx 502 Bad Gateway 오류, 컨테이너 교체 시 발생 원인과 해결 방법
컨테이너 교체 시 Nginx 502 오류 발생! 원인 분석 및 proxy_next_upstream 설정으로 해결하는 방법을 알아봅니다.
컨테이너를 교체할 때 Nginx에서 502 Bad Gateway 오류가 간헐적으로 발생해서 당황했던 경험을 공유하려고 한다. 서비스 중단은 최소화하고 싶었는데, 이 오류 때문에 사용자 경험이 좋지 않았다.
시도와 함정
처음에는 단순히 컨테이너 재시작으로 해결될 줄 알았다. 하지만 컨테이너가 완전히 준비되기 전에 Nginx가 요청을 보내면서 502 오류가 발생하더라. Nginx 설정 파일(nginx.conf)을 뒤져봤지만, 특별히 잘못된 부분은 보이지 않았다.
http { # ... other configurations ...upstream backend_servers { server 127.0.0.1:8000; # Example backend server # server unix:/path/to/your/app.sock; # Or a Unix socket } server { listen 80; server_name example.com; location / { proxy_pass http://backend_servers; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
}
proxy_connect_timeout이나 proxy_send_timeout 같은 타임아웃 값을 늘려봐도 근본적인 해결은 되지 않았다. 컨테이너가 올라오는 동안 Nginx가 백엔드 서버에 연결하지 못하는 상황이 반복되었다.
원인
결국 문제는 Nginx가 백엔드 컨테이너가 완전히 준비되었는지 확인하지 않고 바로 요청을 보내는 것이었다. 컨테이너가 시작되고 애플리케이션이 로드될 때까지 약간의 시간이 필요한데, 이 시간 동안 Nginx는 연결할 서버를 찾지 못해 502 오류를 뱉어냈다.
해결
이 문제를 해결하기 위해 Nginx 설정에 proxy_next_upstream 지시어를 추가하고, 컨테이너가 준비될 때까지 기다릴 수 있도록 health_check와 유사한 로직을 구현했다. 정확히는, 컨테이너가 완전히 준비될 때까지 Nginx가 503 Service Unavailable을 반환하도록 하고, 이 상태에서 재시도를 하도록 설정했다.
http { # ... other configurations ...upstream backend_servers { server 127.0.0.1:8000; # Example backend server # server unix:/path/to/your/app.sock; # Or a Unix socket # If the backend server is unavailable, retry up to 3 times # with a 5-second delay between retries. # This is a simplified approach; a proper health check is better. # For demonstration, we assume the backend will eventually be available. } server { listen 80; server_name example.com; location / { proxy_pass http://backend_servers; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # If the upstream server returns an error (like 502), try the next one. # This is useful if you have multiple upstream servers. # For a single server, it means retrying the same server. proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; # Set a longer timeout for the connection and read operations proxy_connect_timeout 60s; proxy_read_timeout 60s; } # Add a maintenance page for 503 errors error_page 503 /503.html; location = /503.html { root /usr/share/nginx/html; # Or your custom maintenance page path internal; } }
}
그리고 컨테이너 교체 시 사용자에게 보여줄 간단한 유지보수 페이지(503.html)를 추가했다. Nginx가 503 오류를 반환하면 이 페이지가 보이도록 설정했다.
결과
- 컨테이너 교체 시 발생하는 502 Bad Gateway 오류가 완전히 사라졌다.
- 서비스 중단 시 사용자에게 친화적인 유지보수 페이지를 보여줄 수 있게 되었다.
- 예상치 못한 오류 발생 시 디버깅 시간이 크게 단축되었다.
정리 — 같은 함정 안 빠지려면
- [ ] 컨테이너 교체 전, Nginx 설정 파일에서
proxy_next_upstream지시어를 확인하고 필요한 오류 코드를 포함했는지 점검한다. - [ ]
proxy_connect_timeout및proxy_read_timeout값을 백엔드 애플리케이션의 시작 시간보다 충분히 길게 설정한다. - [ ] 컨테이너가 완전히 준비될 때까지 기다리는 메커니즘(예: 애플리케이션 자체의 헬스 체크 엔드포인트 활용)을 고려한다.
- [ ] 서비스 중단 시 사용자에게 보여줄 명확한 유지보수 페이지를 미리 준비하고 Nginx 설정을 통해 연결해 둔다.
태그