안녕하세요, 서버 세팅하시느라 고생 많으시네요.
개인 포트폴리오 수준에서 Nginx 리버스 프록시 구성하시는 거, 정말 기본적인 단계부터 짚고 넘어가야 할 부분이 많아서 막막할 수 있어요.
저도 예전에 비슷한 상황에서 연결 불안정 겪어봤던 경험이 있어서, 몇 가지 실질적으로 도움이 되었던 팁들 위주로 정리해 드릴게요.
일단 말씀하신 '연결 불안정'이나 '끊김' 증상은 대부분 타임아웃 설정이나 연결 유지(Keep-Alive) 설정이 미흡할 때 발생해요.
Django 같은 WSGI/ASGI 기반 백엔드를 Nginx로 프록시할 때는 HTTP 통신 프로토콜 레벨에서 몇 가지 설정을 건드려줘야 안정성이 확 올라가거든요.
--- ### 1.
가장 기본 중의 기본: 타임아웃 관련 설정 (Timeout) 이 부분이 제일 중요하고, 제일 많이 놓치는 부분이에요.
Nginx는 기본적으로 통신에 시간이 지나면 연결을 끊어버리려는 경향이 있어요.
Django 같은 백엔드가 요청을 처리하는 데 시간이 좀 걸리거나, 혹은 요청-응답 사이의 간격(예: 클라이언트가 페이지를 로드하고 API를 호출하기 전에 잠시 멈추는 경우)이 생기면 Nginx가 "응답이 너무 느리네?" 하고 연결을 닫아버릴 수 있거든요.
필수하게 추가해 볼 설정: location 블록 내부나 http 블록에 아래 지시어를 추가해 보세요.
nginx proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; 이게 무슨 뜻인가요? * proxy_connect_timeout: Nginx가 백엔드 서버(Django가 돌아가는 로컬 포트)에 연결을 시도할 때, 연결 성공을 기다리는 최대 시간이에요.
기본값이 너무 짧으면, 서버가 부팅 중이거나 약간의 부하가 걸릴 때 연결 자체를 못 맺고 실패할 수 있어요.
proxy_send_timeout: Nginx가 요청(헤더나 본문 데이터)을 백엔드 서버로 전송할 때, 백엔드로부터 응답을 받지 못하고 대기하는 최대 시간입니다.
proxy_read_timeout: 백엔드 서버가 요청을 받고 실제로 응답 데이터를 보내기 시작해서, 클라이언트에게 모든 데이터를 전송할 때까지 기다리는 최대 시간이에요.
이게 보통 제일 많이 문제가 되는 부분입니다.
백엔드에서 시간이 좀 걸리는 쿼리나 복잡한 로직을 돌리면, 이 시간이 초과되면서 연결이 뚝 끊기는 것처럼 보일 수 있어요.
팁: 개인 프로젝트라면 30초나 60초 정도로 넉넉하게 잡는 것을 추천해요.
만약 API 호출이 매우 길게(예: 1분 이상) 걸리는 작업이 아니라면, 60초 정도면 충분히 넉넉하게 잡을 수 있습니다.
--- ### 2.
연결 유지(Keep-Alive) 및 헤더 문제 요즘 웹 애플리케이션은 보통 여러 요청을 한 번의 연결 세션 내에서 연속적으로 보내는 경우가 많아요.
이때 연결을 계속 열어두는 것이 효율적인데, 이걸 'Keep-Alive'라고 합니다.
설정 확인: Nginx가 클라이언트와 백엔드 간의 연결을 너무 빨리 닫지 않도록 설정해 주는 게 좋아요.
proxy_set_header Connection ""; # 연결 헤더 관련하여 명시적으로 비워주는 것도 도움이 됩니다.
``` **`proxy_http_version 1.1`의 중요성:** HTTP/1.1은 연결을 재사용하는 Keep-Alive 메커니즘을 기본으로 하죠.
이 설정을 명시적으로 해주는 게 안정적인 연결 관리에 도움이 될 때가 많습니다.
**💡 흔한 실수 (헤더 관련):** 만약 Django에서 세션 기반으로 동작하거나, 특정 인증 토큰 같은 것을 주고받는 경우, **Host 헤더**를 제대로 넘겨주지 않으면 백엔드 서버가 요청을 잘못 처리할 수 있어요.
```nginx proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ``` `$host`를 사용해서 클라이언트가 접속한 도메인 이름 그대로 백엔드에 전달해 주는 게 가장 안전합니다.
--- ### 3.
Django/Python 측 고려 사항 (Nginx 바깥의 영역) 이건 Nginx 설정은 아니지만, 연결 안정성을 위해 반드시 확인해야 할 부분이라 같이 말씀드릴게요.
Nginx가 아무리 잘 설정되어 있어도, Django나 WSGI 서버(Gunicorn이나 uWSGI 등) 자체의 설정이 불안정하면 소용이 없어요.
**Gunicorn/uWSGI 사용 시:** 만약 Nginx 뒤에 Gunicorn 같은 프로세서가 돌고 있다면, 이 프로세서의 워커(Worker) 개수나 타임아웃 설정을 점검해 보세요.
1.
**워커 개수:** 서버의 코어 개수(CPU)에 맞게 워커 수를 설정하는 것이 일반적이지만, 트래픽이 매우 적은 개인 프로젝트라면 너무 높게 잡을 필요는 없어요.
(예: CPU 코어 수 * 2 + 1 정도가 가이드라인이긴 하지만, 일단 적당히 시작하는 게 좋아요.) 2.
**프로세스 재시작 주기:** Gunicorn 같은 경우, 장시간 구동 시 메모리 누수나 기타 이유로 프로세스가 불안정해질 수 있어요.
주기적으로 재시작되도록 관리하는 것이 좋습니다.
(이건 운영체제 레벨의 서비스 관리자(systemd 등) 설정을 통해 주기적으로 재시작되게 하는 게 가장 확실해요.) --- ### 4.
종합적인 적용 예시 (요약) 실제 `server` 블록이나 `location` 블록에 넣을 때, 이렇게 묶어서 적용하는 걸 추천합니다.
```nginx location / { # 1.
타임아웃 설정 (넉넉하게 60초로 설정) proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; # 2.
연결 유지 및 헤더 설정 proxy_http_version 1.1; 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 Connection ""; # Keep-Alive 관련 명시 # 3.
백엔드 주소 설정 (Django가 돌아가는 주소: 포트) proxy_pass http://127.0.0.1:8000; # <- 여기에 실제 Django 포트를 넣어주세요.
} ``` **마지막 주의사항:** 위 설정들을 적용하신 후에는 **반드시** Nginx 설정을 테스트하고 리로드 해주셔야 합니다.
`sudo nginx -t` 로 문법 검사를 먼저 하시고, 문제가 없으면 `sudo systemctl reload nginx` (또는 사용하시는 서비스 관리 명령어)로 적용해주세요.
이렇게 설정하시면, 단순히 요청/응답 시간이 길어지거나 연결이 잠시 끊기는 상황에 대한 내구성은 훨씬 좋아질 거예요.
개인 프로젝트 수준에서는 이 정도만 잡고 가셔도 대부분의 '연결 불안정' 문제는 해결될 거라고 보건대요.
혹시 특정 에러 메시지(예: 504 Gateway Timeout)가 뜬다면, 그 메시지를 가지고 다시 질문해주시면 더 구체적인 답변 드릴 수 있을 것 같습니다!