Nginx

Yeji·2023년 11월 21일
0

1. Nginx란?

Nginx는 오픈소스 웹서버 프로그램이다. 정적 파일을 서빙하고 동적 요청을 효율적으로 처리해 WAS의 과부화를 줄인다.

1-1. 역할

Nginx는 웹서버 역할 외에 다음과 같은 기능을 수행할 수 있다.

  • 리버스 프록시 : 클라이언트 요청을 받아 서버로 전달한다.

  • 로드밸런싱 : 클라이언트 요청을 여러 개의 서버로 분산시킬 수 있다. 서버가 과부화되는 것을 막는다.

  • SSL/TLS 지원 : SSL/TLS 프로토콜을 지원해 HTTPS 통신을 구현한다. 클라이언트와 서버 간의 통신을 암호화하는 역할을 한다.

1-2. Event-driven 아키텍처

Apache 웹서버의 경우 하나의 요청에 대해 하나의 프로세스가 할당되는 Process-driven 아키텍처다. 클라이언트 연결이 증가하게 되면 그만큼 많은 프로세스를 할당해야 하기 때문에 메모리 부족 문제가 발생하기 쉽다.

반면 Nginx는 하나의 프로세스가 여러개의 요청을 처리할 수 있고, 유저의 요청을 하나의 event로 보는 Event-driven 아키텍처다. 엔진엑스는 설정 파일을 읽고 워커 프로세스를 생성하는 마스터 프로세스와 유저 요청을 처리하는 워커 프로세스로 이루어져있다. Nginx의 이벤트 루프는 working queue에 이벤트를 추가하고 워커 프로세스가 queue에 있는 이벤트를 처리하도록 한다. 오래 걸리는 작업이라면 Thread Pool에 넘겨 비동기적으로 해당 작업을 처리해 작업 효율을 높인다.

2. Nginx 설정

2-1. 설치

EC2 Ubuntu 기준, 리눅스 명령어를 사용한다.

// 패키지 업데이트
sudo apt-get update

// Nginx 설치
sudo apt-get install nginx

2-2. 구조

Nginx를 설치하면 /etc 하위 폴더에 nginx가 있다. nginx 구조는 다음과 같다.

nginx/
├── conf.d/
│   ├── default.conf
│   └── templates/
├── sites-available/
│   └── default.conf
├── sites-enabled/
│   └── default.conf
├── h5bp/
│   ├── basic.conf
│   ├── location/
│   └── .../
├── custom.d/
│   └── .../
├── mime.types
└── nginx.conf

2-2-1. conf.d

nginx.conf에서 불러올 수 있는 사용자 정의 설정 파일을 저장한다.

이 디렉토리 내에 위치한 파일은 nginx.conf에서 include 지시문을 통해 불러올 수 있다. 각 설정 파일에 특정 기능을 추가해 설정을 모듈화할 수 있으며, 가상 호스트에 대한 설정을 나눠 관리할 수 있다.

[가상 호스트]
하나의 웹서버에서 여러 개의 웹사이트를 호스팅하는 것.
하나의 서버에 여러 개의 도메인이나 IP 주소를 매핑해 서로 다른 웹사이트를 운영할 수 있다.

2-2-2. sites-available, sites-enabled

한 웹서버에서 여러가지 웹서비스를 다른 도메인으로 운영할 때를 대비해 있는 폴더다.

sites-available에 도메인별 설정 파일을 저장하고, sites-enabled에서 심볼릭 링크를 통해 웹서비스를 실행한다. 심볼릭 링크를 설정해놓으면 sites-available에 있는 설정 파일을 읽고 실행한다.

// 설정 파일
sudo vi /etc/nginx/sites-available/example.conf

// 링크 생성
sudo ln -s /etc/nginx/sites-available/example.conf /etc/nginx/sites-enabled/

2-2-3. nginx.conf

Nginx 주요 설정 파일로, 웹서버 기본 설정이 포함되어 있다.

nginx.conf은 다양한 블록으로 구성되어 있으며 가상호스트, HTTP 서버 설정, 위치 설정 등을 포함한다.

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
  • user www-data : nginx 프로세스가 실행되는 권한이다. www-data는 일반적으로 웹서버 프로세스가 실행되는 사용자다. root 권한은 보안상 위험하다.
  • worker_process : 동시에 실행될 nginx 워커 프로세스 수를 설정한다. auto는 시스템 CPU 코어 수에 따라 자동으로 프로세스 수를 조절한다.
  • pid : nginx 프로세스 아이디가 저장되는 경로다.
  • include : 포함시킬 외부 파일 경로를 작성한다.
events {
        worker_connections 768;
        # multi_accept on;
}

events 블록은 주로 nginx 이벤트 처리에 대한 설정을 담당한다. 워커 프로세스와 관련된 설정을 할 수 있다.

  • worker_connections : 각 워커 프로세스가 동시에 처리할 수 있는 연결 수를 지정한다. 서버 성능에 따라 조절한다.
  • multi_aaccept : nginx가 여러 클라이언트의 연결을 받아들일지 여부를 결정한다. 기본값은 off로 nginx는 클라이언트 연결을 순차적으로 처리한다.
http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        # server_tokens off;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ##
        # SSL Settings
        ##

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
        ssl_prefer_server_ciphers on;

        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;
        
        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
}

http 블록은 http 프로토콜로 동작하는 웹서버의 전반적인 설정을 담당한다.

  • keepalive_timeout : 클라이언트 연결이 유지될 시간을 설정한다. 기본은 65다.
  • access_log : 접근 로그가 쌓이는 경로를 설정한다.
  • error_log : 에러 로그가 쌓이는 경로를 설정한다.
  • include : 포함시킬 외부 파일 경로를 설정한다.

sites-enabledserver 블록과 location 블록을 작성한 파일이 담겨있다.

server 블록은 하나의 웹사이트에 관한 설정을 할 수 있다.

server {
    listen 80;
    server_name insideout-movie.site;
}
  • listen : 어떤 포트로 요청을 받을지 설정한다.
  • server_name : 요청을 받을 도메인을 설정한다.

location 블록은 요청에 대해 엔드포인트 별로 응답을 설정할 수 있다.

location /static/ {
        alias /.../staticfiles/;
    }

    location /api {
        include proxy_params;
        proxy_pass http://127.0.0.1:8000;
    }

    location / {
        root /.../dist/;
        index index.html;
        try_files $uri $uri/ /index.html;
    }
  • /static/ : alias를 사용해 정적 파일에 대한 요청은 staticfiles에서 서빙한다.

  • /api : API 요청시 http://127.0.0.1:8000 서버로 요청을 프록시한다.

  • / : 사용자 요청에 대한 기본 설정이다. 배포한 프론트 애플리케이션을 서빙하도록 설정했다.

  • index : 요청에 특정 경로가 명시되지 않아도 기본 파일을 반환하도록 한다.

  • try_files : nginx 순서대로 파일이나 폴더를 찾을 때 사용한다. 특정 파일이나 폴더가 존재하지 않을 때 다른 파일이나 경로로 리다이렉트를 설정한다.

    $uri : 현재 요청된 URI에 해당하는 파일을 찾는다.
    $uri/ : 현재 요청된 URI에 해당하는 폴더를 찾는다.
    /index.html : 앞의 두 경우 모두 실패한 경우 /index.html로 리다이렉트한다.
📍 SPA의 경우에는 try_files 설정이 필수적이다.
대표적으로 리액트는 단일 index.html 파일을 가지고 react-router로 url에 따라 DOM을 갈아 끼운다.
이 때 기본 경로 (/)로 들어온 요청에는 index.html을 정상적으로 응답하지만,
기타 경로 (/mypage/)로 요청이 들어왔을 경우 index.html을 찾지 못해 404를 반환한다.
따라서 파일을 찾지 못했을 경우 index.html을 반환할 것을 설정해줘야 잘 동작한다.

2-3. SSL(Secure Sockets Layer)

SSL은 웹브라우저와 웹서버 간 데이터 통신을 보완하는 데 사용되는 프로토콜이다.

웹사이트에 SSL을 적용해 https 프로토콜로 안전하게 통신할 수 있다. SSL은 전송계층에 속하며 TCP 위에서 동작한다.

2-3-1. Certbot

Certbot은 SSL 인증서를 발급하고 자동으로 갱신해주는 도구다. nginx에 등록하면 Let's Encrypt를 통해 SSL 인증서를 발급한다.

// 설치
sudo snap install --classic certbot

// 심볼릭 링크 생성
sudo ln -s /snap/bin/certbot /usr/bin/certbot

// nignx에 등록
sudo certbot --nginx

그러면 다음과 같이 Certbot이 관리(managed by Certbot)하는 영역이라며 설정이 추가된다.
listen 443 ssl : https 프로토콜이라 443 포트가 설정되어 있는 것을 확인할 수 있다.

server {
    server_name insideout-movie.site;

    location /static/ {
        alias /.../staticfiles/;
    }

    location /api {
        include proxy_params;
        proxy_pass http://127.0.0.1:8000;
    }

    location / {
        root /.../dist/;
        index index.html;
        try_files $uri $uri/ /index.html;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/insideout-movie.site/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/insideout-movie.site/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = insideout-movie.site) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    if ($host = www.insideout-movie.site){
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80;
    server_name insideout-movie.site;
    return 404; # managed by Certbot
}
profile
채워나가는 과정

0개의 댓글

관련 채용 정보