최근 수정일: 2022/05/24
Django로 구축한 API 서버와 React를 연결하고 배포하기 위해서 Nginx를 사용해보았다.
Django와 React를 연결하기 위해서 웹 서버와 Nginx에 대한 이해가 반드시 필요했고,
앞으로 Nginx를 공부하며 알게 되는 지식들을 최대한 자세히 이 포스팅에 담을 예정이다.
그리고 Nginx만 다루는 게 아니라 웹 서버의 전반적인 이해를 위해서 조금이라도 궁금한 점이 생기면 옆길로 계속 새어나갈 예정이다.
Nginx란? #1
간단히 말해서 경량화된 소프트웨어 웹 서버이다.
Nginx는 Single-thread로 동작하며 비동기 non-blocking I/O 이벤트 기반으로 요청을 처리한다.
따라서 적은 자원으로 효율적인 트래픽 처리가 가능하다.
(멀티 스레드를 사용한다면 요청이 들어올 때마다 스레드가 생성되고 context-switching 횟수가 증가하므로 자원이 낭비될 수 있다)
웹 서버?
다른말로 HTTP Server라고도 한다. 웹 브라우저의 파트너로서 서버의 정보를 제공하는 소프트웨어라고 할 수 있다.
대표적으로 Nginx, Apache가 있다.
웹 서버는 인터넷 네트워크 위에서 HTTP 프로토콜을 이용해 HTML, CSS, Javascript, image/mediafile과 같은 정적인 정보들을 웹 브라우저에 전송한다.
웹 브라우저?
크롬, 사파리, 네이버 웨일, 파이어폭스, 인터넷 익스플로러? 등을 웹 브라우저라고 한다.
웹 서버와 통신하며 html문서나 파일을 출력해준다.
HTTP 프로토콜?
웹에서 데이터를 주고받기 위한 일종의 규약이다.
HTTP 프로토콜은 상태를 가지고 있지 않다. 따라서 이전 데이터 요청과 다음 데이터 요청이 완전히 분리되어 독립적으로 관리할 수 있다.
이와 같은 이점으로 당장 받은 요청 이외의 정보를 추가적으로 관리할 필요가 없어지고, 다수의 요청 및 서버의 부하를 줄일 수 있는 성능의 향상을 가져왔다.
HTTP 프로토콜은 일반적으로 TCP/IP 통신 위에서 동작하며 기본 포트는 80번이다.
URL (Uniform Resource Locators)
서버에 자원을 요청하기 위해서 입력하는 영문 주소.
HTTP의 주요 메서드
html form에서 method를 지정해줄 때 사용하는 것들
- GET : 존재하는 자원에 대한 요청
- POST : 새로운 자원을 생성
- PUT : 존재하는 자원에 대한 변경
- DELETE : 존재하는 자원에 대한 삭제
HTTP 상태코드
2xx - 성공
200번대의 상태 코드는 대부분 성공을 의미한다.
- 200 : GET 요청에 대한 성공
- 204 : No Content. 성공했으나 응답 본문에 데이터가 없음
- 205 : Reset Content. 성공했으나 클라이언트의 화면을 새로 고침 하도록 권고
- 206 : Partial Conent. 성공했으나 일부 범위의 데이터만 반환
3xx - 리다이렉션
300번대 상태 코드는 대부분 클라이언트가 이전 주소로 데이터를 요청하여 서버에서 새로운 URL로 리다이렉트를 유도하는 경우이다.
- 301 : Moved Permanently, 요청한 자원이 새 URL에 존재
- 303 : See Other, 요청한 자원이 임시 주소에 존재
- 304 : Not Modified, 요청한 자원이 변경되지 않았으므로 클라이언트에서 캐싱된 자원을 사용하도록 권고. ETag와 같은 정보를 활용하여 변경 여부를 확인
4xx - 클라이언트 에러
400번대 상태 코드는 대부분 클라이언트의 코드가 잘못된 경우이다. 없는 자원을 요청했거나 요청 권한 등이 잘못된 경우에 발생한다.
- 400 : Bad Request, 잘못된 요청
- 401 : Unauthorized, 권한 없이 요청. Authorization 헤더가 잘못된 경우
- 403 : Forbidden, 서버에서 해당 자원에 대해 접근 금지
- 404 : Not found, 요청한 자원이 서버에 없음
- 405 : Method Not Allowed, 허용되지 않은 요청 메서드
- 409 : Conflict, 최신 자원이 아닌데 업데이트하는 경우. ex) 파일 업로드 시 버전 충돌
5xx - 서버 에러
500번대 상태 코드는 서버 쪽에서 오류가 난 경우이다.
- 501 : Not Implemented, 요청한 동작에 대해 서버가 수행할 수 없는 경우
- 503 : Service Unavailable, 서버가 과부하 또는 유지 보수로 내려간 경우
앞에서 설명한 URL, Method, 상태 코드를 종합해서 그림으로 나타내 보면 다음과 같다.
TCP/IP?
TCP/IP 는 두 개의 프로토콜(TCP, IP)을 사용하여 데이터 통신을 하는 것을 의미한다.
IP(Internet Protocol)는 복잡한 네트워크 망을 패킷 통신 방식(데이터를 작은 조각들로 나뉘어서 보내는 방식)을 사용해 데이터를 가장 효율적인 방법으로 보내는 작업을 한다.
TCP(Transmission Control Protocol)는 조각난 데이터를 받으면서 순서가 맞지 않다면 정렬하고, 누락된 데이터를 점검하여 다시 요청하는 작업을 한다.
2021.09.24 정리한 TCP에 관한 내용이다.
Nginx란? #2
1. HTTP Server로서 정적 파일을 Serve 해준다
클라이언트(유저)로부터 요청을 받았을 때 WAS를 거치지 않고 요청에 맞는 정적 파일을 응답해주는 HTTP server로서 활용할 수 있다.
HTML, CSS 같은 정적인 리소스에 대한 요청을 Nginx가 처리해준다.
React의 build 된 파일들도 정적인 리소스라고 볼 수 있고 따라서 Nginx가 index.html 같은 메인 페이지를 랜더링 해줄 수 있다.
2. Reverse Proxy Server로서 Client와 Server를 중개해 준다.
Reverse Proxy Server로서 Client의 Request와 Server의 Response를 중개하는 서버로 동작하게 할 수 있다. 이 과정에서 nginx는 로드밸런서로서의 역할을 수행할 수 있다.
동적으로 계산되거나 전달되어야 하는 사항들은 WAS에게 맡긴다.
WAS (Web Application Server)
웹 서버로부터 오는 동적인 요청들을 처리하는 서버이다. 흔히 사용하는 웹 프레임워크를 사용해 구축하는 백엔드를 WAS라고 생각하면 될듯하다. 주로 데이터베이스 서버와 같이 관리된다.
좀 더 자세한 설명은 바로 아래에 있다.
Django와 WSGI, Gunicorn
Django가 클라이언트의 요청을 웹서버를 통해서 받을 때 WSGI라는 것을 반드시 거치게 된다.
WSGI(Web Server Gateway Interface)는 이름만 봐도 웹에 대한 인터페이스 임을 알 수 있다. 그래서 범용적인 웹 인터페이스라고 생각할수도 있지만 WSGI는 오직 파이썬을 위한 인터페이스이다. 웹 서버에서 전달해주는 HttpRequest들을 파이썬이 이해할 수 있는 언어로 해석해서 파이썬 프로그램으로 보내주는 역할을 맡게된다. Django는 Python으로 만들어진 프레임워크이고 따라서 Django와 웹서버를 결합하기 위해선 WSGI가 필요하다.
Django에는 runserver라고 불리는 개발환경에 적합한 서버를 돌릴 수 있는 기능이 있다. 하지만 runserver는 단일 스레드로 동작하기 때문에 요청이 많아지면 처리능력이 현저히 떨어지는 단점 때문에 실제 배포환경에서는 사용해서는 안되는 방법이다. 그래서 WSGI를 사용하게된다. WSGI는 멀티 스레드를 생성할 수 있기 때문에 요청이 많아져도 안정적으로 처리가 가능하다. WSGI의 종류에는 uwsgi, gunicorn이 양대산맥으로 있지만 최근 gunicorn의 성능이 uwsgi보다 좋아졌기 때문에 대부분 gunicorn을 사용하는 추세이다.
그래서 Django의 WSGI로 gunicorn을 사용하게되고 Django와 gunicorn을 합쳐서 WAS라고 부른다.
흐름
Nginx와 관련된 개념들
Proxy?
포워드 프록시와 리버스 프록시를 설명하기 전에 Proxy 자체에 대해서 알아보자
클라이언트가 데이터를 요청하면 서버가 요청한 리소스를 가져다줄 것이다. 하지만 중간에 클라이언트의 요청을 서버로 보내주는 Proxy라고 불리는 서버가 하나 존재하게 된다.
이처럼 프록시는 중계 서버라고 이해하면 편하다. 클라이언트와 서버가 서로 직접적으로 통신하지 않고, 프록시 서버를 이용해서 리소스를 전달하며 보안, 트래픽 분산, 캐시 사용(속도 향상) 등 여러 장점을 가지는 중요한 서버이다.
Forword Proxy
일반적인 프록시 서버를 말하며, 클라이언트와 웹 서버의 중개역할로 클라이언트가 요청 시 Proxy서버는 해당 요청을 웹 서버로 중계해 자원을 가져오는 개념이다.
프록시 서버는 클라이언트가 요청하기 전까지 웹 서버의 주소를 알 수 없다는 게 특징이다.
예를 들어 회사 내부망에서 인터넷의 www.google.com 으로 연결해 달라고 서버에 요청을 보내면 이때 프록시 서버를 호출하게 되는데 이러한 방식이 포워드 프록시이다.
포워드 프록시 방식은 정해진 사이트에만 연결이 가능하게끔 설정이 가능해서 주로 회사 내부의 인트라넷 등 보안이 중요한 환경에서 주로 사용된다.
Reverse Proxy
클라이언트와 서버 사이에(서버 앞에) 위치하여 보안, 로드밸런싱 역할을 한다. 그래서 클라이언트가 특정 리소스를 요청을 하면 프록시 서버가 WAS에 요청 후 응답 받은 리소스를 클라이언트에게 전달해주는 개념이다.
예를 들자면 이 방식은 특정 ip주소에서 제공하는 api서버를 호출하기 위해서 인터넷에 있는 클라이언트가 리버스 프록시 서버에 api를 요청하여 응답을 받는 방식이다.
리버스 프록시 서버는 실제 서버가 어디서 동작하는지 감추는 역할을 한다. 클라이언트는 리버스 프록시를 통해서 리소스를 요청하기 때문에 서버의 IP주소를 알 수 없다. 그리고 리버스 프록시 서버는 실제 서버들에 대한 주소를 매핑하고 있어야 한다.
내가 느끼기에 포워드 프록시는 제한에 걸리는 것들 빼고 모든 심부름을 다 수행해주는 심부름꾼 같고, 리버스 프록시는 특정 가게와 연결되어 있으면서 손님이 A라는 물건을 요청하면 연결된 가게의 A 물건만 전문적으로 갖다 주는 역할을 수행하는 것 같다.
로드밸런싱?
서버의 부하(Load)를 분산(Balancing)시키는 기술이다.
많은 클라이언트들(이용자들)이 하나의 웹 사이트에 접속해서 해당 서버의 트래픽이 늘어날 때 여러 대의 서버를 이용해서 요청을 처리하도록 한다. 각 서버의 부하량, 속도 저하 등을 고려해서 서버의 가중치, 스케줄링 등을 결정해 트래픽을 적절히 분산시키는 과정을 로드밸런싱이라고 한다.
로드밸런싱의 장점?
한 서버의 부하를 분산시킨다는 게 당연히 장점이 된다.
값싼 비용으로 다수의 서버를 증설하여 관리할 수 있기 때문에 고가의 서버를 구매할 필요가 없다.
1대의 서버가 멈춰도 서비스가 중단되지 않는다. 마찬가지로 서버를 늘리는 과정에서도 서비스가 중단되지 않는다.
Nginx에서 제공하는 로드밸런싱 방법에 3가지가 있다.
1. Round Robbin : 운영체제 스케줄링 방법에도 있는 방식이다. 주어진 서버들을 순차적으로 돌아가면서 선택하는 방법이다.
2. Least-connected : 현재 접속자 수가 가장 적은 서버를 선택하는 방법이다.
3. ip-hash : hash function을 사용해서 클라이언트 ip를 hash 한 결과에 따라서 다른 서버를 할당해주는 방법이다.
API 란?
API(Application Programming Interface)는 특정 서비스나 응용 프로그램에서 소스 코드를 공개하지 않고 요청한 기능을 제공하기 위해서 이용한다.
서버 API는 web 서버에 클라이언트가 어떠한 요청을 하였을 때 그에 맞는 응답을 줄 수 있는 endpoint를 Web을 통하여 노출한 것이다.
예를 들어 http://12.34.56.78:8000/api/company 라는 endpoint에 서버와 연결된 데이터베이스에 있는 모든 회사의 주가정보를 json으로 반환하는 api를 열어놓았다면 사용자는 해당 endpoint를 요청하여 데이터를 json으로 받아올 수 있다.
API의 역할
모든 사람들이 서비스들의 고유 데이터베이스에 접근해서는 안된다.
API는 이를 방지하기 위해서 서버와 데이터베이스에 대한 출입문 역할을 하며, 허용된 클라이언트, 서버에 대해서만 데이터를 넘겨준다.
django-nginx로 api를 서버를 구축했다면 리버스 프록시인 nginx가 요청할 때만 django는 데이터를 넘겨주도록 해야 한다.
API는 모든 접속을 표준화하기 때문에 클라이언트/운영체제와 상관없이 누구나 동일한 데이터를 얻을 수 있게 한다.
REST API 란?
API의 endpoint 아키텍처 스타일이다.
HTTP 메서드를 사용하면 진정한 RESTful API라고 할 수 있다.
REST = REpresentational State Transfer 라고 한다.
- REST API는 리소스를 중심으로 디자인 된다. 클라이언트에서 요구하는 모든 종류의 데이터, 서비스가 리소스에 포함된다.
- 리소스마다 해당 리소스를 고유하게 식별할 수 있는 URI인 식별자가 존재한다.
아래는 특정 유저에 대한 URI이다.
https://localhost:8000/api/v1/user/1
- 클라이언트는 리소스를 위와 같은 URI를 통해 서버에 요청하면서 서버와 상호작용한다. 일반적으로 많은 Web API가 데이터 교환 형식으로 JSON을 사용한다. 예를 들어 위 URI에 대한 GET 요청은 다음과 같은 JSON을 반환할 수 있다.
{"username": "admin", "email": "aaa@google.com"}
- REST API는 균일한 인터페이스를 사용하므로 클라이언트와 서버의 분리에 많은 도움이 된다. 가장 일반적인 작업은 GET, POST, PUT, PATCH, DELETE이다.
- REST API를 사용하는 HTTP 요청은 독립적이어야 하고 임의의 순서로 발생할 수 있기 때문에, 요청 사이에 일시적으로 상태 정보를 유지할 수 없다. 이러한 조건 때문에 웹 서비스의 확장성이 우수하다. 클라이언트와 특정 서버 사이의 연결 및 선호도를 유지할 필요가 없기 때문이다. 따라서 모든 서버는 모든 클라이언트의 모든 요청을 처리할 수 있다는게 REST의 특징이다.
REST API는 리소스를 중심으로 API 디자인을 구성해야 한다.
https://myrestapi.com/user // Good
https://myrestapi.com/create-user // Avoid
리소스 URI는 동사(리소스에 대한 작업)가 아닌 명사(리소스)를 기반으로 해야한다.
👆내가 느끼는 REST 아키텍텨의 핵심이라고 생각한다.
몇 가지 예를 통해 REST 형식을 가지는 URI에 대해 감을 잡아보자
https://myrestapi.com/user
위 URI에 HTTP GET 요청을 보낸다는건 어떤걸 의미하는 것일까?
특정 user의 정보를 불러온다? - ❌
user를 생성한다? - ❌
특정 user를 수정한다? - ❌
특정 user를 삭제한다? - ❌
우선 특정 유저를 지칭하는 리소스 번호가 포함되지 않았기 때문에 특정 유저에 대한 동작은 아닐 것이다.
그리고 파라미터가 없는 GET요청을 보냈기 때문에 user를 생성하는 동작도 아닐 것이다. 일반적으로 리소스 생성을 위한 메소드는 POST이다.
따라서 위 URI는 모든 user의 정보를 리스트로 받아오는 API가 아닐까 추측해 볼 수 있다.
URI에는 일관적인 명명 규칙을 적용한다. 그리고 리소스에 대한 URI를 계층 구조로 구성하는 것이 좋다.
예를 들어 /board는 현재 생성되어 있는 게시판 종류 리스트에 대한 경로이고, /board/1는 ID가 1인 게시판의 경로이다.
이러한 접근 방식을 사용하면 웹 API를 직관적으로 유지할 수 있다.
또한 많은 Web API는 매개 변수가 있는 URI 경로를 기반으로 요청을 라우팅할 수 있으므로 개발자는 /board/<int:board_id> 에 대한 경로를 정의할 수 있다.
[GET] https://myrestapi.com/board/1
1번 게시판에 속한 정보를 요청하는 URI
[GET] https://myrestapi.com/board/1/post
1번 게시판에 속한 모든 post 정보를 요청하는 URI
RESTful API에서 사용하는 일반적인 HTTP 메서드는 다음과 같다.
- GET : 지정된 URI에서 리소스의 정보를 요청한다.
- POST : 지정된 URI에 새로운 리소스를 생성한다. 요청 시 보내는 data는 리소스의 정보를 담고있다. 리소스를 만들지 않는 작업을 할 수 도 있다.
- PUT : 지정된 URI에 리소스를 만들거나 대체한다. 요청 시 보내는 data는 리소스를 만들 또는 업데이트할 정보를 담고 있다.
- PATCH : 리소스의 부분 업데이트를 수행한다. 요청 시 보내는 data는 리소스에 적용할 변경 내용을 담고 있다.
- DELETE : 지정된 URI의 리소스를 제거한다.
리소스 | POST | GET | PUT | DELETE |
/board | 새 게시판 만들기 | 모든 게시판 검색 | 게시판 다수 업데이트 | 모든 게시판 제거 |
/board/1 | 1번 게시판 즐겨찾기 | 1번 게시판에 대한 세부정보 검색 | 게시판 1의 세부 정보 업데이트 | 1번 게시판 제거 |
/board/1/post | 1번 게시판에 대한 새 post 만들기 | 1번 게시판의 모든 post 검색 | 1번 게시판의 post 다수 업데이트 | 1번 게시판의 모든 post 제거 |
nginx.conf
nginx가 작동하는 방식을 결정하는 구성파일이다.
docker에서 nginx이미지를 받고 컨테이너를 만들면 기본적으로 /etc/nginx/nginx.conf 에 위치한다.
호스트에 자신이 원하는 설정이 담긴 nginx.conf 파일을 만들고, docker 컨테이너 내부에 nginx가 설치되어 있다면, 기본 위치에 있는 nginx.conf와 bind volume을 걸어서 사용하기도 한다.
-> 호스트에 있는 nginx.conf가 카피되어 컨테이너의 nginx.conf로 덮어쓰기된다.
nginx를 원하는대로 구동되게 하기위해서 nginx.conf에 있는 컨텍스트들을 살펴보자
worker_processes
worker_processes는 발생하는 이벤트를 처리하는 프로세스의 수를 정의하는 지시어이다.
일반적으로 CPU의 core 수만큼 할당하고, auto로 설정하면 자동으로 값을 알맞게 설정해준다.
worker_processes auto;
events
events 블록을 알아보자.
events{
worker_connections 1024;
use epoll;
}
worker_connections 는 하나의 프로세스가 동시에 몇 개의 연결을 처리할 수 있는지 설정해준다. (보통 512 또는 1024로 설정한다)
events{
use epoll;
}
위에서 지정한 epoll은 Linux에서 socket을 관리하는 데 사용하는 방식 중 하나로, epoll 외에도 poll, select 방식이 있습니다.
이 중 poll과 select는 해당 프로세스에 연결된 모든 connection file을 스캔하지만, epoll은 수천개의 file descriptor를 처리할 수 있도록 보다 효율적인 알고리즘을 사용하고 있어 대량 요청이 발생하는 시스템에 적합하다고 합니다.
use epoll은 epoll 방식으로 이벤트를 처리해준다는 뜻이다.
epoll은 linux 소켓을 관리하는 방법중 하나인데 이외에도 poll, select 방식이 있다.
epoll 방식은 nginx의 모든 소켓 파일을 찾아보는게 아니라 현재 활성화 된 소켓만 확인해서 연결을 설정해주기 때문에 모든 소켓파일을 확인하는 poll 방식에 비해서 업그레이드 된 버전이다.
http
http 블록은 nginx로 들어오는 웹 트래픽에 대한 처리 방법과 방향을 설정해주는 블록이다.
나는 지금까지 http 컨텍스트에서는 upstream 블록과 server 블록만 사용해보았다.
http {
upstream project_home {
server project_home:8000;
}
client_max_body_size 75M;
server{
...
}
upstream과 server 사이에 있는 client_max_body_size가 보이는가?
client_max_body_size는 nginx를 통해서 이동하는 파일의 최대 크기를 지정해 줄 수 있는 지시어이다.
upstream
upstream 'HOST명' 형식으로 사용한다.
아래에서 URI 라우팅을 위해 사용되는 server의 통합 닉네임이라고 생각하면 편하다.
upstream 내부에 있는 server 블록에는 호스트명과 해당하는 port를 함께 명시해주면 된다.
나는 Docker를 통해서 django WAS 서버를 nginx와 한 네트워크로 묶어서 같이 사용하기 때문에 project_home이라는 컨테이너명을 호스트명으로 사용할 수가 있다.
따라서 컨테이너명이 HOST의 이름이 되기 때문에 upstream 옆에 적을 수 있다.
docker를 사용하지 않는다면 123.34.67.34 같은 ip 주소를 적으면 된다.
upstream project_home {
// least_conn;
// ip_hash;
server project_home:8000 weight=5 slow_start=30s;
server project_home:8001;
server project_home:8002 backup;
}
upstream에서 사용하는 load balancing method를 알아보자
기본적으로 nginx는 round-robbin 방식을 사용한다.
least_conn은 클라이언트와 가장 적게 연결된 서버 순으로 연결을 우선한다.
ip_hash는 클라이언트 IP 를 hash 해서 '특정 클라이언트는 특정 서버로 연결'하는 설정이다.
부하가 골고루 분산되지 않고 특정 서버에 몰릴 수 있는 위험이 있다.
코드를 보면 포트가 서로 다른 서버 3개(8000, 8001, 8002)가 열려있다.
첫 번째 서버에 weight(가중치)가 5가 주어져 있다.
이는 해당 서버가 5번 연결이 된 후에 8001번 서버로 연결이 넘어간다는 의미이다.
그리고 첫 번째 서버에는 slow_start=30s 가 설정되어있다.
이는 최근에 장애로부터 복구한 서버에 요청이 폭주하지 않도록 slow_start 에 주어진 시간(30초)만큼 기다려 주는 의미이다.
세 번째 서버에는 backup이 설정되어있다.
평소에는 동작하지 않다가, 모든 서버가 오류 상태일 때 동작하는 서버이다.
server
서버 상에서 2개 이상의 웹 사이트를 실행할 수 있는 방법이다.
server{
listen 443 ssl;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/{호스트명}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{호스트명}/privkey.pem;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
include mime.types;
}
server 블럭을 사용하면
- 사이트 정적 문서 루트를 지정하고,
- 각 사이트에 대해 별도의 보안 정책을 만들고,
- 사이트의 오류 페이지를 통일할 수 있고,
- 각 사이트에 대해 서로 다른 SSL 인증서를 사용하는 등의 작업을 할 수 있다.
listen
Nginx가 요청을 받아들일 포트를 설정한다.
server {
listen 80;
listen 443 ssl;
......
}
default값은 80이다.
80 대신에 원하는 다른 값을 입력할 수 있다.
https를 적용하려면 listen 443 ssl;
을 입력하면 된다.
include
웹 서버의 라우팅
location
특정 경로에 대하여 적절한 WAS로 요청을 넘겨줄 수 있게 해주는 블록
http {
upstream apigateway {
server apigateway_service:8000;
}
server{
listen 80;
location /api {
proxy_pass http://apigateway;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
}
}
}
- root :
- alias :
- index :
- try_files :
- allow :
- deny :
- proxy_http_version 1.1 : 리버스 프록시를 위한 HTTP 프로토콜 버전을 정의한다. 기본 값은 1.0이다. 웹 소켓 및 활성 연결을 유지하려면 버전 1.1을 사용해야 한다.
- proxy_cache_bypass $http_upgrade : 캐시에서 응답을 가져오지 않을 조건을 설정한다. (웹소켓 캐싱 제한)
- Upgrade $http_upgrade 및 Connection "upgrade" : 응용프로그램이 웹 소켓을 사용하는 경우 Upgrade와 Connection 헤더가 필요하다.
- Host $host : $host 변수에는 요청을 보낸 호스트 이름 또는 호스트 요청 헤더 필드의 호스트 이름 또는 요청과 일치하는 서버 이름이 포함된다.
- X-Real-IP $remote_addr : 실제 방문자 원격 IP 주소를 리버스 프록시 서버로 전달한다.
- X-Forwarded-$proxy_add_x_forwarded_for : 클라이언트가 프록시 처리한 모든 서버의 IP 주소를 포함하는 목록이다. X-Forwarded-For 헤더값은 조작이 가능하기 때문에 애플리케이션에서 Client IP 값으로 어떠한 작업이 필요할 경우 올바르게 동작하지 않을 수 있다.
- X-Forwarded-Proto $scheme : HTTPS 서버 블록 내에서 사용할 경우 프록시 서버의 각 HTTP 응답이 HTTPS로 다시 작성된다.
- X-Forwarded-Host $host : 클라이언트가 요청한 원래 호스트를 정의한다.
- X-Forwarded-Port $server_port : 클라이언트가 요청한 원래 포트를 정의한다.
공부에 도움이 된 사이트들 ☆
공식문서 Beginner's Guide
전반적인 Nginx 이해 #1
Web Server & WAS #1
Reverse Proxy, Forword Proxy 개념 #1
root vs alias
전반적인 Nginx 이해 #2
Nginx 라우팅
HTTP 프로토콜
Reverse Proxy 개념 #2
Reverse Proxy 개념 #3
Nginx 로드 밸런싱 개념
Django WAS
Nginx Proxy 모듈
API에 관해서
'DevOps > Nginx' 카테고리의 다른 글
리버스 프록시의 정의와 설정 방법 (0) | 2022.03.07 |
---|---|
[Nginx] ip_hash method 주의사항 (backup X) (0) | 2021.11.20 |
[Nginx] Nginx HTTPS 및 cerbot SSL 인증서 적용 (0) | 2021.11.14 |