Nginx 502 Bad Gateway, 결국 해결했습니다! (RPA 엔지니어 삽질기)

약 10분 읽기

안녕하세요. RPA 엔지니어 황민입니다. 오늘은 제가 개인 서버를 운영하면서 겪었던, 정말이지 악몽 같았던 Nginx 502 Bad Gateway 오류를 잡았던 경험을 공유하려고 합니다. 특히 n8n과 WordPress를 리버스 프록시로 설정하면서 수도 없이 겪었던 이 오류와의 사투는, 저를 밤새 모니터 앞에서 괴로워하게 만들었죠. 이 글이 저와 같은 고통을 겪고 계신 분들께 작은 등불이 되기를 바랍니다.

502 Bad Gateway, 대체 왜 뜨는 걸까요?

502 Bad Gateway 오류는 간단히 말해, Nginx가 백엔드 서버(애플리케이션 서버)로부터 유효하지 않은 응답을 받았을 때 발생하는 문제입니다. 마치 중간에서 소통을 담당하는 Nginx가 뒷단에서 일하는 서버와 말이 통하지 않아 발생하는 엉뚱한 상황인 셈이죠. 제 경우에는 n8n 워크플로우 자동화 도구와 WordPress 블로그를 제 개인 서버에서 운영하고 있었는데, 이 두 서비스를 Nginx를 통해 외부에서 접근 가능하도록 리버스 프록시 설정을 하던 중에 이 502 오류가 연달아 발생했습니다. 처음에는 ‘아, 설정 하나 잘못했겠지’ 하고 쉽게 생각했는데, 이게 정말 집요하게 저를 괴롭혔습니다.

처음에는 단순히 proxy_pass 설정에서 오타가 있거나, 방화벽 문제겠거니 생각했습니다. 하지만 아무리 설정을 뒤져봐도 문제는 해결되지 않았고, 로그를 파고들수록 더 복잡한 문제들이 얽혀 있는 듯 보였습니다. 마치 미로 찾기 같았죠. 밤늦게까지 이어지는 삽질에, ‘내가 이 서버를 왜 운영하고 있을까’ 하는 회의감마저 들 때도 있었습니다. 하지만 맞벌이 부부로서 서울에서 청약 준비도 하고, ISA 계좌로 ETF 자동 투자도 하면서 제 삶을 자동화하고 효율화하는 것에 큰 재미를 느끼는 사람으로서, 이 문제를 해결하지 않고 넘어갈 수는 없었습니다. 결국, 끈질긴 노력 끝에 이 502 오류의 주범들을 찾아내고 해결할 수 있었습니다.

서버 사진 — 리버스 프록시 설정, 그 험난한 여정
Photo by Brett Sayles on Pexels

리버스 프록시 설정, 그 험난한 여정

제가 겪었던 502 오류의 원인은 크게 몇 가지로 압축할 수 있었습니다. 개인 서버 운영 경험이 어느 정도 있었지만, Nginx 리버스 프록시 설정은 처음이었기에 겪는 시행착오들이었습니다.

1. upstream 타임아웃 문제

가장 먼저 의심했던 부분은 백엔드 서버의 응답 시간이 너무 오래 걸려서 Nginx가 기다리다 지쳐버리는 경우였습니다. 특히 n8n 같은 경우, 복잡한 워크플로우를 실행하거나 외부 API와 통신할 때 시간이 꽤 소요될 수 있습니다. Nginx의 기본 타임아웃 설정은 비교적 짧은 편인데, 백엔드 서버의 응답이 이보다 길어지면 Nginx는 ‘연결이 끊어졌다’ 혹은 ‘응답이 없다’고 판단하고 502 오류를 반환합니다. 저는 proxy_connect_timeout, proxy_send_timeout, proxy_read_timeout 등의 지시어를 늘려보며 이 문제를 해결하려고 시도했습니다.

처음에는 proxy_read_timeout 값을 300초(5분) 정도로 늘렸는데, 여전히 502 오류가 발생했습니다. 그래서 아예 600초(10분)까지 늘려보기도 했고, proxy_connect_timeout과 proxy_send_timeout도 함께 조정했습니다. 하지만 이게 근본적인 해결책이 되지는 못했습니다. 물론 이 타임아웃 설정은 중요한 부분이지만, 제 경우에는 다른 더 근본적인 문제가 있었던 거죠.

2. 소켓 경로 설정의 함정

리버스 프록시 설정을 할 때, HTTP(S) 프로토콜을 사용하는 것이 아니라 Unix 소켓을 통해 백엔드 서버와 통신하도록 설정할 수도 있습니다. 이는 같은 서버 내에서 여러 서비스를 운영할 때 효율적인 방법 중 하나입니다. 저는 n8n을 Docker로 실행하고 있었는데, Docker 컨테이너와 Nginx가 통신할 때 이 소켓 경로 설정이 매우 중요했습니다. proxy_pass 지시어에서 백엔드 서버의 주소를 지정할 때, IP 주소나 도메인 대신 소켓 파일의 경로를 지정하게 됩니다. 예를 들어, proxy_pass http://unix:/path/to/your/n8n.sock; 와 같이 말이죠. 이때, Nginx가 해당 소켓 파일에 접근할 수 있는 권한이 없거나, 소켓 파일의 경로가 잘못 지정된 경우 502 오류가 발생합니다. 저는 처음 Nginx 설정 시, Docker 컨테이너 내부에 생성된 소켓 파일의 경로를 잘못 지정했거나, Nginx가 실행되는 사용자 권한 문제로 접근하지 못하는 상황이 발생했던 것 같습니다.

이 문제를 해결하기 위해 Dockerfile과 Nginx 설정 파일, 그리고 파일 권한 설정을 꼼꼼히 확인했습니다. ls -l 명령어를 통해 소켓 파일의 소유권과 권한을 확인하고, Nginx 워커 프로세스가 실행되는 사용자가 해당 소켓 파일에 접근할 수 있도록 권한을 조정했습니다. 또한, Docker Compose 설정을 통해 Nginx와 백엔드 서비스 간의 네트워크 통신 설정을 다시 한번 점검했습니다. 이 과정에서 Docker의 네트워크 모드 설정이 의외로 복잡하다는 것을 다시 한번 느꼈습니다.

3. proxy_pass의 Trailing Slash 함정

이것이야말로 정말 예상치 못했던, 하지만 너무나도 흔하게 발생하는 함정이었습니다. proxy_pass 지시어에서 URL 뒤에 슬래시(/)를 붙이느냐, 붙이지 않느냐에 따라 Nginx가 요청을 전달하는 방식이 달라집니다. 만약 proxy_pass http://backend.example.com/; 와 같이 슬래시를 붙이면, Nginx는 클라이언트가 요청한 URI를 백엔드 서버의 루트 경로(/)에 추가하여 전달합니다. 예를 들어, 클라이언트가 http://yourdomain.com/api/users 를 요청했다면, Nginx는 http://backend.example.com/api/users 로 전달하는 것이 아니라 http://backend.example.com/api/users/ 처럼 마지막에 슬래시를 붙여서 전달하려고 시도합니다.

반면, proxy_pass http://backend.example.com; 와 같이 슬래시를 붙이지 않으면, Nginx는 클라이언트가 요청한 URI를 그대로 백엔드 서버에 전달합니다. 즉, http://yourdomain.com/api/users 요청은 http://backend.example.com/api/users 로 전달됩니다. 제가 n8n과 WordPress를 설정할 때, 이 슬래시 하나 때문에 백엔드 서버에서 예상치 못한 경로로 요청이 전달되어 404 오류나 502 오류가 발생하는 경우가 많았습니다. 백엔드 애플리케이션이 특정 경로 구조를 기대하고 있는데, Nginx가 슬래시를 잘못 붙여 전달하면 애플리케이션은 해당 요청을 처리하지 못하고 오류를 반환하게 되는 것이죠.

이 문제를 해결하기 위해 저는 Nginx 설정 파일을 수십 번 수정했습니다. location 블록과 proxy_pass 지시어의 조합을 바꿔가며 테스트했고, 결국 백엔드 애플리케이션의 특성에 맞는 슬래시 사용법을 찾아냈습니다. 이 경험을 통해 proxy_pass 뒤의 슬래시 하나가 얼마나 큰 차이를 만드는지 뼈저리게 느꼈습니다. 정말 사소한 차이가 엄청난 문제를 일으킬 수 있다는 것을 직접 경험한 것이죠.

해결까지 걸린 시간과 저만의 팁

제가 이 502 Bad Gateway 오류를 완전히 해결하기까지 걸린 시간은 약 3일 정도였습니다. 물론 중간중간 다른 업무도 병행했지만, 순수하게 이 문제에 매달렸던 시간을 합치면 꽤 많은 시간을 투자했죠. 그동안 시도했던 방법들을 요약하자면 다음과 같습니다.

  • Nginx 에러 로그 및 액세스 로그 정밀 분석
  • 백엔드 서버(n8n, WordPress) 애플리케이션 로그 확인
  • proxy_connect_timeout, proxy_send_timeout, proxy_read_timeout 값 조정
  • proxy_buffering, proxy_buffers, proxy_buffer_size 설정 테스트
  • Unix 소켓 경로 및 권한 설정 점검
  • proxy_pass 지시어의 Trailing Slash 여부에 따른 설정 변경
  • Docker 네트워킹 설정 검토
  • 백엔드 애플리케이션의 자체적인 타임아웃 설정 확인

이 과정에서 가장 중요했던 것은 끈기와 체계적인 접근이었습니다. 단순히 설정을 바꿔보는 것이 아니라, 어떤 설정을 왜 바꾸는지 이해하고, 변경할 때마다 로그를 확인하며 변화를 기록하는 것이 중요했습니다. 그리고 제가 터득한 몇 가지 팁을 공유하자면:

  • 로그를 믿으세요: Nginx의 에러 로그는 문제 해결의 가장 중요한 단서입니다. /var/log/nginx/error.log 파일을 꼼꼼히 살펴보세요.
  • 단계별로 테스트하세요: 한 번에 여러 설정을 바꾸지 마세요. 한 가지 설정 변경 후 로그를 확인하고, 문제가 해결되지 않으면 다음 단계로 넘어가세요.
  • Docker 네트워크를 이해하세요: Docker 환경에서 리버스 프록시를 설정한다면 Docker의 네트워킹에 대한 이해가 필수적입니다.
  • 커뮤니티의 도움을 받으세요: 저도 Stack Overflow나 관련 커뮤니티에서 많은 도움을 받았습니다. 비슷한 문제를 겪었던 사람들의 경험담을 참고하는 것이 좋습니다.

마무리하며

개인 서버를 운영하면서 겪는 이런 문제들은 때로는 좌절감을 안겨주기도 하지만, 동시에 서버 운영 능력과 문제 해결 능력을 키워주는 소중한 경험이기도 합니다. n8n과 WordPress를 Nginx 리버스 프록시로 설정하면서 겪었던 502 Bad Gateway 오류와의 사투는 저에게 Nginx 설정의 미묘한 차이와 백엔드 서버와의 통신 방식에 대한 깊은 이해를 심어주었습니다. 앞으로도 홈 IoT 구축이나 개인 서버 운영 등 자동화와 효율화를 위한 다양한 시도를 계속할 예정입니다. 여러분도 혹시 비슷한 어려움을 겪고 계시다면, 너무 낙담하지 마시고 끈기를 가지고 문제 해결에 나서시길 바랍니다. 분명 해결책이 있을 테니까요!

긴 글 읽어주셔서 감사합니다. 다음에는 더 유익한 정보로 돌아오겠습니다.

황민

황민 (Hwang Min)

IT·RPA·AI 분야 개발자. 웹앱 개발, UiPath RPA, n8n 자동화 실무 경력 4년. AI·금융·IT 트렌드를 현장 개발자 시각으로 분석합니다.

댓글 남기기

𝕏fin