Nginx 설정 마스터하기: 필수 지시어 완벽 해설

가장 많이 사용하는 Nginx 지시어(http, server, location, proxy_pass, try_files, gzip, TLS, 서비스 리로드)를 이해합니다.

Nginx 설정 마스터하기: 필수 지시어 설명

각 지시어가 어디에 위치할 수 있는지 이해하면 Nginx 설정이 훨씬 쉬워집니다. proxy_pass, root, try_files 규칙이 잘못된 컨텍스트에 있으면 Nginx가 설정을 거부하거나 예상치 못한 방식으로 요청을 처리할 수 있습니다.

이 가이드는 정적 파일 제공, 애플리케이션 리버스 프록시, 압축 활성화, 변경 사항을 안전하게 리로드할 때 사용하는 필수 지시어를 설명합니다.

Nginx 설정 구조

Nginx 설정 파일은 일반적으로 Linux 패키지에서 /etc/nginx/ 아래에 있습니다. 주요 파일은 보통 /etc/nginx/nginx.conf이며, /etc/nginx/conf.d/의 파일을 포함하는 경우가 많습니다. Debian 및 Ubuntu 패키지는 일반적으로 sites-available/sites-enabled/를 사용하지만, 다른 많은 배포판에서는 사용하지 않습니다.

설정은 블록 또는 지시어로 구성된 계층 구조입니다. 주요 블록은 다음과 같습니다:

  • events: 연결 처리를 구성합니다.
  • http: HTTP 전체 설정과 가상 서버를 포함합니다.
  • server: 포트와 호스트 이름에 대한 가상 서버를 정의합니다.
  • location: 일치하는 요청 URI를 처리하는 방법을 선택합니다.

지시어는 Nginx의 동작을 제어하는 키-값 쌍입니다. 전역적으로 사용되거나 블록 내에 중첩될 수 있습니다.

필수 지시어 설명

http 블록

http 블록은 HTTP 트래픽에 전역적으로 적용되는 설정을 포함합니다. 웹 서버의 공통 설정을 정의하는 곳입니다.

  • include: 이 지시어는 다른 설정 파일을 포함할 수 있게 하여 설정을 모듈화하는 데 도움을 줍니다. 다른 웹사이트나 애플리케이션의 설정을 분리하는 데 일반적으로 사용됩니다.

    http {
        include       mime.types;
        default_type  application/octet-stream;
    
        # conf.d 디렉토리에서 서버 설정 포함
        include /etc/nginx/conf.d/*.conf;
    }
    
  • log_format: Nginx 액세스 및 오류 로그의 사용자 정의 로그 형식을 정의합니다. 상세한 로깅 및 분석에 필수적입니다.

    http {
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                            '$status $body_bytes_sent "$http_referer" '
                            '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  /var/log/nginx/access.log  main;
        error_log   /var/log/nginx/error.log;
        # ... 기타 http 지시어
    }
    
  • sendfile: 커널이 디스크에서 클라이언트로 직접 파일을 전송하여 사용자 공간을 우회함으로써 파일 전송을 최적화합니다. 성능을 위해 on으로 설정합니다.

    http {
        sendfile        on;
        # ...
    }
    
  • tcp_nopushtcp_nodelay: HTTP 응답에 대한 TCP 동작을 조정합니다. tcp_nopush는 패킷 전송을 최적화하기 위해 sendfile과 함께 일반적으로 사용되며, tcp_nodelay는 keepalive 연결에서 지연을 방지하는 데 도움을 줍니다.

    http {
        tcp_nopush     on;
        tcp_nodelay    on;
        # ...
    }
    

server 블록

server 블록은 가상 서버를 정의하여 Nginx가 동일한 서버에서 다른 도메인 이름이나 IP 주소에 대한 요청을 처리할 수 있게 합니다.

  • listen: 서버가 들어오는 연결을 수신할 IP 주소 및/또는 포트를 지정합니다.

    server {
        listen 80;
        listen [::]:80;
        server_name example.com www.example.com;
        # ...
    }
    
  • server_name: 서버의 이름을 정의합니다. Nginx는 이를 사용하여 들어오는 요청의 Host 헤더와 일치시킵니다.

    server {
        listen 80;
        server_name mydomain.org *.mydomain.org;
        # ...
    }
    
  • root: 문서 루트를 설정합니다. Nginx는 요청 URI를 이 디렉토리에 추가하여 파일 경로를 구성합니다.

    server {
        listen 80;
        server_name localhost;
        root /var/www/html;
        index index.html index.htm;
        # ...
    }
    
  • index: 디렉토리가 요청될 때 제공할 기본 파일을 지정합니다.

    server {
        # ...
        index index.html index.htm default.html;
        # ...
    }
    
  • error_page: 특정 HTTP 상태 코드에 대한 사용자 정의 오류 페이지를 정의합니다.

    server {
        # ...
        error_page 404 /404.html;
        location = /404.html {
            root /usr/share/nginx/html;
            internal;
        }
        # ...
    }
    

location 블록

location 블록은 요청 URI를 일치시키고 Nginx가 이를 처리하는 방법을 결정하는 데 사용됩니다. 애플리케이션의 다른 부분에 대한 라우팅을 구성하는 곳입니다.

  • URI 일치: 위치는 정확한 문자열, 접두사 또는 정규 표현식과 일치할 수 있습니다. 정확한 일치는 =, 정규 표현식은 ~ 또는 ~*, 일반 접두사는 URI 접두사로 일치합니다.

    location /images/ {
        # /images/로 시작하는 요청에 대한 지시어
    }
    
    location = /favicon.ico {
        # /favicon.ico에 대한 정확한 일치
    }
    
    location ~ \.php$ {
        # .php로 끝나는 파일에 대한 정규 표현식 일치
    }
    
  • proxy_pass: 요청을 업스트림 서버로 전달합니다. 후행 슬래시에 주의하세요. Nginx가 일치하는 접두사를 다시 쓰는 방식을 변경하기 때문입니다.

    location /api/ {
        proxy_pass http://backend-service:8080/;
        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;
    }
    
  • alias: 위치를 전체 원래 URI를 추가하지 않고 파일 시스템 경로에 매핑합니다. 주 문서 루트 외부에 저장된 정적 자산에 자주 사용됩니다.

    location /static/ {
        alias /var/www/app/assets/;
    }
    

    alias를 사용할 때는 디렉토리 매핑을 위해 위치와 경로 모두에 후행 슬래시를 포함하세요. alias는 일치하는 위치 접두사를 별칭 경로로 대체하는 반면, root는 URI를 루트 경로에 추가합니다.

  • try_files: 지정된 순서로 파일의 존재를 확인하고 첫 번째로 발견된 파일을 제공하거나 지정된 코드/URI를 반환합니다.

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

    이는 단일 페이지 애플리케이션에서 일반적입니다. 요청된 파일이나 디렉토리가 없으면 Nginx가 index.html을 제공하여 클라이언트 측 라우터가 경로를 처리할 수 있게 합니다.

보안 및 성능 지시어

  • ssl_certificatessl_certificate_key: HTTPS 구성에 필수적입니다. 이 지시어는 SSL 인증서와 개인 키 파일을 가리킵니다.

    server {
        listen 443 ssl;
        server_name secure.example.com;
    
        ssl_certificate /etc/letsencrypt/live/secure.example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/secure.example.com/privkey.pem;
    
        # ... 기타 SSL 설정
    }
    
  • gzip: 선택한 응답 유형에 대해 gzip 압축을 활성화하거나 비활성화합니다. 텍스트 자산의 전송 크기를 줄이는 경우가 많지만, 대부분의 이미지와 같이 이미 압축된 파일은 압축하지 않는 것이 좋습니다.

    http {
        gzip on;
        gzip_vary on;
        gzip_proxied any;
        gzip_comp_level 6;
        gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
        # ...
    }
    
  • expires: 정적 자산의 캐싱 헤더를 제어합니다. 지문이 있는 파일에는 긴 캐시 수명을 사용하고, 배포 간에 동일한 URL을 유지하는 파일에는 짧은 수명을 사용합니다.

    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 30d;
        add_header Cache-Control "public";
    }
    

일반적인 Nginx 명령어

Nginx를 관리하고 설정 변경 사항을 적용하려면 다음 명령어를 자주 사용합니다:

  • 설정 테스트: Nginx 설정 파일의 구문 오류를 확인합니다.

    sudo nginx -t
    
  • 설정 리로드: 활성 연결을 끊지 않고 Nginx 설정을 정상적으로 리로드합니다.

    sudo systemctl reload nginx
    # 또는
    sudo service nginx reload
    
  • Nginx 재시작: Nginx 서비스를 중지했다가 시작합니다.

    sudo systemctl restart nginx
    # 또는
    sudo service nginx restart
    
  • 상태 확인: Nginx 서비스의 현재 상태를 표시합니다.

    sudo systemctl status nginx
    # 또는
    sudo service nginx status
    

최소 작동 예제

이 예제는 디스크에서 단일 페이지 앱을 제공하고 API 요청을 앱 서버로 프록시합니다:

server {
    listen 80;
    server_name example.com;

    root /var/www/example.com;
    index index.html;

    location /api/ {
        proxy_pass http://127.0.0.1:3000/;
        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;
    }

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

리로드하기 전에 항상 sudo nginx -t를 실행하세요. 이 습관 하나로 구문 오류가 다운타임으로 이어지기 전에 잡을 수 있습니다.

핵심 요약

대부분의 Nginx 실수는 컨텍스트와 경로 처리에서 발생합니다. HTTP 전체 설정은 http에, 호스트별 규칙은 server에, URI 라우팅은 location에 넣고, 리로드하기 전에 항상 nginx -t로 변경 사항을 테스트하세요.