본문 바로가기
소프트웨어개발

Nginx 502 Bad Gateway 해결: Docker upstream·포트·헬스체크 점검

by 아빠띠띠뽀 2026. 9. 22.

Nginx의 502 Bad Gateway는 브라우저 요청을 받은 Nginx가 뒤쪽 애플리케이션(upstream)에서 정상 응답을 얻지 못했다는 뜻입니다. 설정을 무작정 바꾸기 전에 오류 로그, 애플리케이션 상태, Docker 네트워크, 포트, 시간 제한 순서로 좁혀야 복구 시간을 줄일 수 있습니다.

1. Nginx 오류 로그 한 줄부터 분류한다

sudo nginx -t
sudo tail -n 100 /var/log/nginx/error.log

Nginx 공식 upstream 문서는 여러 백엔드 서버를 정의하고 실패 처리와 시간 제한을 구성하는 방법을 설명합니다. 로그의 connection refused는 주소나 포트에서 프로세스가 수신하지 않는 경우, host not found in upstream은 이름 해석 문제, upstream timed out은 연결 또는 응답 지연을 우선 의심할 수 있습니다.

로그 문구가능성 높은 원인우선 확인

connection refused 앱 중지·포트 불일치 컨테이너 상태와 listen 포트
host not found 서비스명·네트워크 문제 Compose 서비스명과 DNS
upstream timed out 앱 지연·타임아웃 앱 로그와 처리 시간
no live upstreams 모든 백엔드 비활성 upstream 목록과 헬스 상태

502 오류는 Nginx 자체보다 upstream 연결 주소, 포트, 응답 상태에서 원인을 찾는 경우가 많습니다.

2. 애플리케이션이 실제로 응답하는지 확인한다

docker compose ps
docker compose logs --tail=100 app
docker compose exec nginx curl -v http://app:3000/health

컨테이너가 Up 상태라는 사실만으로 애플리케이션 준비가 끝났다고 볼 수 없습니다. Nginx 컨테이너 안에서 서비스명과 내부 포트로 health endpoint를 호출하면 네트워크와 애플리케이션 문제를 동시에 구분할 수 있습니다. health endpoint가 없다면 가벼운 루트 경로나 상태 확인 API를 사용합니다.

3. 컨테이너 안의 localhost는 자기 자신이다

Nginx와 앱이 서로 다른 컨테이너라면 proxy_pass http://localhost:3000의 localhost는 Nginx 컨테이너를 가리킵니다. 같은 Compose 네트워크에서는 http://app:3000처럼 서비스명과 컨테이너 포트를 사용합니다. Docker Compose 공식 문서도 서비스가 기본 네트워크에서 서비스명으로 발견된다고 설명합니다.

4. 호스트 포트와 컨테이너 포트를 구분한다

ports: - "8080:3000"에서 8080은 호스트에서 접근할 공개 포트이고 3000은 컨테이너 내부 포트입니다. 같은 Compose 네트워크의 Nginx는 보통 app:3000으로 연결해야 합니다. 자세한 구조는 Docker 컨테이너 네트워크와 포트 연결에서 확인할 수 있습니다.

5. 시작 순서와 준비 상태를 구분한다

depends_on만으로 애플리케이션이 요청을 받을 준비까지 기다린다고 가정하면 초기 502가 생길 수 있습니다. 애플리케이션에 healthcheck를 정의하고, 필요하면 의존 서비스가 healthy가 된 뒤 시작하도록 구성합니다. Docker healthcheck와 자동 재시작에서 상태 점검 설계를 함께 볼 수 있습니다.

6. 타임아웃을 늘리기 전에 느린 원인을 확인한다

Nginx의 proxy_connect_timeout, proxy_read_timeout, proxy_send_timeout을 조정할 수 있지만 긴 값은 장애를 숨기고 사용자 대기 시간만 늘릴 수 있습니다. 앱의 DB 연결, 외부 API, CPU와 메모리, 이벤트 루프 정체를 먼저 측정합니다. 파일 변환이나 긴 작업은 요청 안에서 끝내기보다 작업 큐와 상태 조회 방식이 적합할 수 있습니다.

7. 복구 체크리스트와 FAQ

  1. nginx -t로 문법을 확인합니다.
  2. 오류 로그의 정확한 upstream 주소와 문구를 기록합니다.
  3. Nginx 컨테이너에서 upstream health URL을 직접 호출합니다.
  4. 서비스명, 내부 포트, 공통 네트워크를 확인합니다.
  5. 앱 로그와 자원 사용량을 보고 원인을 수정한 뒤 재시험합니다.

Q. Nginx를 재시작하면 해결되나요?
일시적인 DNS나 연결 상태는 바뀔 수 있지만 원인을 제거한 것은 아닙니다.

Q. 504와 502는 어떻게 다른가요?
둘 다 게이트웨이 오류지만 504는 정해진 시간 안에 upstream 응답을 받지 못한 상황을 더 직접적으로 나타냅니다.

Q. 브라우저에서만 실패하면?
Nginx 뒤 앱 호출이 성공한다면 HTTPS, Host 헤더, WebSocket 업그레이드, CORS 같은 앞단 조건을 추가로 확인합니다.

공식 자료: NGINX upstream module · NGINX proxy module · Docker Compose networking (확인일: 2026-09-22)