What is NGINX
일반적으로 webserver라 하면 http 요청이 들어오면 필요한 작업을 수행하는 서버를 의미합니다.
즉, 브라우저에서 읽을 수 있는 html 파일 등을 전달해 주는 역할을 합니다.
하지만 단순한 정적파일의 제공으로는 동적 파일 렌더링등을 수행할 수 없기 때문에 webserver는 요청을 받으면 웹서버에서 요청을 받아 그 요청을 외부 프로그램에 넘겨주면, 외부 프로그램이 프로그램 파일을 읽어 html로 반환하는 단계를 거치게 되며, 이것을 CGI 라고 합니다.
대표적인 CGI 로는 php fpm 등이 있습니다.
* FAST CGI(Common Gateway Interface) 란 무엇인가?
FastCGI는 상호 작용 프로그램을 웹 서버와 통신하기 위한 바이너리 프로토콜이다.
FastCGI는 초기 공용 게이트웨이 인터페이스(CGI)의 변형이다.
FastCGI의 주 목적은 웹 서버와 CGI 프로그램 간 통신 시 발생되는 부하를 줄임으로써 서버가 한 번에 더 많은 웹 페이지 요청을 관리할 수 있게 하는 것이다.
* php-fpm
nginx가 요청을 받아 php인 경우 cgi 인 php fpm에게 요청을 전달하고 거기서 php 코드를 실행한 뒤에 요청을 다시 받아온다.
Forward Proxy & Reverse Proxy
NGINX 는 Web Server 로써 일반적으로 기업에서 서비스를 배포할 때 reverse proxy server의 역할을 수행한다.
Nginx 에 대해 설명하기 전에 먼저 forward proxy 와 reverse proxy의 개념부터 설명하고자 한다.
먼저, forward proxy server란 사용자가 원하는 정보를 좀 더 빨리 받게 하기 위해 중간에 요청을 가로채는 것이라 볼 수 있다. 가령 target.com 이라는 주소로 어떤 정보를 받아오고 싶은 유저가 있다고 생각해 보자.
이 유저는 주소창에 target.com 을 입력하고 데이터를 받아올 것이며, 이 유저는 자신이 보고 있는 정보가 target.com 에서 보낸 정보라고 생각할 것이다. 하지만 대부분의 경우 유저가 받아온 정보는 실제로 target.com에 있는 정보가 아닌 중간의 프록시 서버에서 이전에 받아놓은 target.com 의 정보를 전달해 주는 것이다.
이러한 proxy server 는 많은 이점을 제공해 주는데, 가령 우리가 목적으로 하는 target.com 의 경우 우리의 ip 주소에 대해서는 알수가 없고, 우리가 사용하는 proxy 서버의 url 에 대해서만 알 수 있다.(하지만 대부분의 경우 browser가 우리의 정보를 제공하기 때문에 사실상은 다 알수 있다..!)
또한, proxy server 는 이미 알고 있는 정보에 대해서 해당 데이터를 cache 하기 때문에 추가적인 요청 없이 바로 우리에게 원하는 정보를 전달해주기 때문제 네트워크 속도의 관점에서도 더욱 빠르게 동작한다.
NGINX 는 이러한 forward proxy 의 기능도 수행할 수 있지만, 대부분의 경우 reverse proxy 의 용도로 사용되는데, 이는 http server 의 보안 문제 해결과 로그 수집 등 여러 이점을 가지기 때문에 사용된다.
가령, 사용자는 proxy.com 이라는 url 로 요청을 주고 실제 서버의 위치인 target.com url 을 유저로 부터 접근을 불가능 하게 막고, 해당 서버를 VPN 에 구성함으로써 보안을 높일 수 있다.
How does it works?
NGINX 서버는 nginx 그룹의 nginx 라는 유저로 모든 프로세스를 실행한다.
요청이 들어오면 nginx 는 해당 요청의 hostname 을 보고 설정된 서버들 중 어떤 서버를 사용할지 선택한다.
NGINX 에는 다양한 서버 설정을 할 수 있으며 이는 /etc/nginx/conf.d/
디렉토리에 수많은 conf 파일의 설정들 중에 어떤 서버 설정을 사용할지 결정하는데 있어 hostname 을 사용한다.
여기서 일치하는 hostname이 있다면 해당 설정대로 serving 하되, 만약 일치하는 hostname 이 없다면 default server
를 사용하며 이는 다음과 같이 server 에서 listen 하는 설정에 default_server
태그가 붙어있는 서버를 선택한다.
1 | server { |
어떤 서버로 부터 serving 할지 결정되었다면, nginx 는 url 패스를 읽어들이고 이를 location 과 비교하여 일치하는 리소스를 찾는 작업을 거치게 된다. 때문에, nginx 에는 여러개의 location 을 설정할 수 있으며, 이 중에서 가장 긴 location path를 우선적으로 선택하게 된다.
1 | server { |
Where to save resources
서버란 특정 리소스를 제공해주는 역할을 하며, 때문에 서버가 제공할 리소스를 저장하는 공간이 필요하다.
nginx 는 기본적으로 /usr/share/nginx
디렉토리 내에 기본적이 리소스들을 보관한다.
하지만, 해당 디렉토리의 리소스들은 nginx 가 전역적으로 사용하기 위한 50x.html
과 같은 에러 페이지 리소스 등을 비롯한 nginx 어플리케이션 레벨에서의 리소스를 저장하는 공간이므로 실제 서버의 리소스는 이곳에 보관하지 않도록 한다.
대신, /var/www/example.com/
디렉토리를 컨벤션으로 사용한다.
Basic Configuration
NGINX 의 세부 설정은 /etc/nginx/nginx.conf 파일에서 관리된다.
하지만, 이 설정파일은 NGINX 서버 자체에 대한 설정파일로써 웹서비스를 서비스한다면 이 환경 설정은 반드시 etc/nginx/conf.d/example.com.conf
과 같은 파일에 설정을 해야 한다.
nginx.conf
파일에서는 nginx 에서 발생하는 error 및 access log 의 저장 위치를 설정하고, 설정파일들의 위치를 명시하여 다른 설정파일을 적용하는 등, 특정 server에 종속된 것이 아니라 nginx 어플리케이션 자체의 설정을 해 준다.
간혹 apache 서버를 사용하던 유저들은 아파치 서버 양식인 /etc/apache/sites-available
와 유사하게 etc/nginx/sites-available
에 서버 설정을 하는 경우가 있는데 이는 좋지 않은 패턴이니 지양하도록 한다.
nginx.conf
1 | user nginx; |
기본적으로 nginx 는 /etc/nginx/conf.d/default.conf
에서 최초의 웹 서버 설정을 해주는데, 별도의 설정파일을 추가한 이후에는 default.conf
파일을 제거하거나 중복된 설정을 없애 주어야 한다. 그렇지 않으면 해당 파일이 default configuration 으로 동작하여 사용자가 한 설정을 덮어써서 설정 내용이 반영이 되지 않게 된다.
개발자는 다음과 같이 example.com.conf 와 같은 설정파일을 작성할 수 있으며 여러 개의 서버와 location 을 지정하고, error page 및 proxy 등 다양한 설정을 할 수 있다.
/etc/nginx/conf.d/example.com.conf
1 | server { |
Serving static file and access to local file system
다음과 같이 특정 url 에 파일 시스템 경로를 mapping 함으로써 특정 url 이 정적 파일들을 서빙하게 할 수 있다.
1 | server { |
위 코드는 /image 로 오는 요청을 file system 에 매핑하여 요청자가 직접 file system 경로를 통해 리소스를 받아올 수 있게 해준다. 만약 특정 파일 형태만 정적 파일 시스템에 접근하도록 하고 싶은 경우 다음과 같이 regular expression 을 통해 해결 할 수 있다.
1 | server { |
Reverse Proxy
NGINX 서버는 간편하게 Reverse Proxing 을 할 수 있게 해 주며, 다음과 같은 간단한 설정을 통해 reverse proxy 서버를 구축할 수 있다.
1 | server { |
위 예제는 localhost/example1/proxy
로 들어온 요청을 http://naver.com/example1
로 proxing 해주는 설정파일이다.
Subdomain
서비스를 출시할때 흔히 다음과 같은 서브 도메인 양식을 가지고 리소스에 접근할 필요가 있게 된다.
가령 관리자 페이지를 위한 admin.example.com 이라던가 혹은 개발서버를 위한 dev.example.com 과 같이 여러 subdomain 이 필요하게 된다. nginx 는 host name 을 인식하여 간편하게 subdomain 을 reverse proxing 해주며 다음과 같은 세팅을 통해 간편하게 이를 적용할 수 있다.
다음 예제는 localhost 환경에서 앞에 example1 이라는 prefix 를 주고, 이를 reverse proxing 해주는 설정파일이다.
1 | server { |
SSL
많은 서비스들은 http 프로토콜의 보안을 위해 https 프로토콜을 사용하며 이를 위해서는 443 port 를 통한 SSL 레벨에서의 통신이 필요하다.
이러한 요청을 처리하기 위해서는 다음과 같이 443 port 를 ssl 레벨에서 listen 해야 한다.
1 | server{ |
GZIP
NGINX 는 통신시에 데이터를 줄이기 위해 gzip 압축을 통한 리소스 압축을 제공한다.
이는 다음과 같은 설정을 통해 할 수 있다.
1 | server { |