네트워크

nginx 설정 알아보기

삼록이 2025. 11. 10. 12:41

nginx의 설정은 크게 두 계층으로 나뉜다.

  • 전역(Global) 설정 / conf파일
  • 개별 사이트 설정  - site-available/ 폴더

 

1.nginx.conf 파일

nginx 설치 후 etc/nginx 경로에 들어가면 nginx.conf 란 이름으로 위치해있는 파일이다.

이 파일에는 nginx의 전역 설정이 정의되어있는 곳으로 

프로세스, worker, 리소스, 로깅, 모듈, 공통 설정이 정의되어있다.

즉, nginx 전체적인 설정을 담당하는 곳이다.

user  www-data;             # nginx 워커 프로세스가 어떤 리눅스 실행 계정으로 권한될 지 지정(마스터 프로세스는 root로 실행됨)
worker_processes  auto;     # CPU 코어 개수만큼 워커 프로세스 자동 설정
pid /run/nginx.pid;         # PID 파일 경로

events {
    worker_connections  1024;  # 각 worker가 처리할 수 있는 최대 동시 연결 수
    multi_accept on;           # 여러 연결을 동시에 수락
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    # 전역 로그 설정
    access_log  /var/log/nginx/access.log;
    error_log   /var/log/nginx/error.log;

    # 사이트별 설정 포함
    include /etc/nginx/sites-enabled/*;
}

 

프로세스.(참고로 프로세스란? 운영체제(OS)입장에서 실행 중인 하나의 프로그램 단위)

 

nginx는 2단계 프로세스 구조로 되어있다.

마스터 프로세스와 워커프로세스

 

마스터 프로세스는 nginx의 시작, 중지, 설정 리로드 등 전체적인 nginx를 관리하고

워커프로세스는 실제로 HTTP 요청을 받아서 응답을 돌려준다. 클라이언트 연결(브라우저 요청)을 처리하고, 파일 읽기, 리버스 프록시, 로드밸런싱을 수행하는 nginx의 핵심 단위이기도 하다.

 

ps -ef | grep nginx를 입력하면 nginx의 프로세스들을 확인할 수 있다.

 

 설정 파일에서 worker_processes  auto; 라고 명시했기에 워커프로세스의 개수는 CPU의 코어 수 만큼 생성된다.

그래서 4코어에 맞게 4개의 워커 프로세스가 생성된 것이다.

그리고 events 블록에서 woker_connections 1024로 설정했기에 워커 4개 * 1024 = 4096개의 동시 요청에 대해 처리가 가능하다.

(event 블록은 nginx의 이벤트 처리 방식을 제어한다-  즉 worker가 네트워크 연결을 어떻게 수락할 지를 정의)

user  www-data;             # nginx 프로세스 실행 계정
worker_processes  auto;     # CPU 코어 개수만큼 워커 프로세스 자동 설정
pid /run/nginx.pid;         # PID 파일 경로

events {
    worker_connections  1024;  # 각 worker가 처리할 수 있는 최대 동시 연결 수
    multi_accept on;           # 여러 연결을 동시에 수락
}

 

 

리소스 설정

리소스 설정은 아래의  sendfile 부분과 keepalive_timeout부분이다.

로깅설정은 nginx.conf파일의 http{}블록에서 설정하는 곳으로 로그를 쌓을 위치와 파일을 말한다.

http블록 안에는 MIME타입, 로그, 압축, 캐시, 프록시, 보안 설정 등 모든 웹 관련설정이 들어간다.

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    # 전역 로그 설정
    access_log  /var/log/nginx/access.log;
    error_log   /var/log/nginx/error.log;

    # 사이트별 설정 포함
    include /etc/nginx/sites-enabled/*;
}

 

 


2.Sites- available

nginx.config가 전역설정을 담당했다면, 하나의 nginx의 여러 웹사이트를 물려 운영할 때 각 사이트마다 설정을 독립적으로 담당하는 곳이 sites-available 폴더에 있는 파일이다(처음엔 default란 이름으로 파일이 있을 것이다.).

이곳에는 각 도메인에 대한 포트,도메인 이름,정적 파일 경로,백엔드 프록시, SSL인증서, 보안/캐시 정책등을 저장할 수 있다.

 

예시)

server {
    listen 80;
    server_name myapp.com www.myapp.com;

    # 1️⃣ 모든 HTTP 요청을 HTTPS로 리다이렉트
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name myapp.com www.myapp.com;

    # 2️⃣ SSL 인증서 경로
    ssl_certificate     /etc/nginx/ssl/myapp.crt;
    ssl_certificate_key /etc/nginx/ssl/myapp.key;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;

    # 3️⃣ 보안 헤더
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";
    add_header X-XSS-Protection "1; mode=block";
    server_tokens off;
    autoindex off;

    # 4️⃣ 정적 파일 루트 (React 빌드 경로)
    root /var/www/myapp/dist;
    index index.html;

    # 5️⃣ 정적 파일 요청 처리
    location / {
        try_files $uri /index.html;
    }

    # 6️⃣ API 요청은 내부 백엔드로 프록시 전달
    location /api/ {
        proxy_pass http://192.168.10.21:8080/api/;

        # 요청 헤더 전달
        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;

        # 대용량 업로드 허용
        client_max_body_size 100M;

        # CORS (개발용, 실제 배포 시 제한 필요)
        add_header 'Access-Control-Allow-Origin' 'https://myapp.com' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type' always;

        if ($request_method = OPTIONS) {
            add_header Content-Length 0;
            add_header Content-Type text/plain;
            return 204;
        }
    }

    # 7️⃣ 이미지, CSS, JS 캐싱 (브라우저 캐시 30일 유지)
    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 30d;
        add_header Cache-Control "public, no-transform";
    }

    # 8️⃣ 보안: 민감 파일 접근 차단
    location ~ /\.env { deny all; return 404; }
    location ~* \.(yml|properties|log|sql)$ { deny all; return 404; }

    # 9️⃣ 로그 (이 사이트 전용)
    access_log /var/log/nginx/myapp_access.log;
    error_log  /var/log/nginx/myapp_error.log;
}

 

 


 

보통은 하나의 도메인에 하나의 sever{}블록 안에 정적 자원 제공+ 리버스 프록시 + 보안/캐시 정책을  관리한다.

즉 server{}은 이 도메인으로 들어오는 요청을 이렇게 처리하라고 정의하는 과정이다.

 

server {
    listen 80;
    server_name myapp.com www.myapp.com;

    # 1️⃣ 모든 HTTP 요청을 HTTPS로 리다이렉트
    return 301 https://$host$request_uri;
}

listen은 이 서버 블록이 수신할 포트를 지정하는 것이다.

즉 HTTP 기본 포트 80을 열어서 요청을 받고, sever_name에 지정한 두 도메인에 대해 HTTPS 로 리다이렉트 하겠다는 의미다.

301은 영구 리다이렉트를 나타내는 상태코드고  $host는 현재 요청한 도메인 $request_uri는 요청한 경로(ex./login)을 그대로 붙여준다는 의미다.

 

server {
    listen 443 ssl http2;
    server_name myapp.com www.myapp.com;

 HTTPS용 443 포트를 연다는 의미며 ssl은 인증서 사용, http2는 최신 프로토콜을 지원한다는 의미다.

 

	# 2️⃣ SSL 인증서 경로
    ssl_certificate     /etc/nginx/ssl/myapp.crt;
    ssl_certificate_key /etc/nginx/ssl/myapp.key;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;

ssl_certificate는 HTTPS에 사용할 공개인증서(crt) 파일 경로.

ssl_certificate_key는 인증서의 개인키 파일 경로

ssl_protocols는 허용할 TLS 버전

ssl_prefer_server_ciphers on 은 클라이언트보다는 서버에서 지정한 암호화 방식을 우선 사용하겠다는 의미다.

즉, https:// 접속 시 어떤 인증서로 암호화할지를 정의하는 부분이다.

 

 # 3️⃣ 보안 헤더
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";
    add_header X-XSS-Protection "1; mode=block";
    server_tokens off;
    autoindex off;

추가로 server_tokens off 는 nginX 버전 정보 노출을 막는 설정이다.
기본적으로 nginx는 에러 페이지나 응답헤더에 자기 버전을 표시하기 때문이다.

autoindex off는 nginx는 기본적으로  요청한 경로 안에 index.html이 없으면 그 디렉토리의 파일 목록을 자동으로 보여주는 기능이 있는데 이는 보안에 위협이므로 off를 해두는 것이 맞다.

 

  # 4️⃣ 정적 파일 루트 (React 빌드 경로)
    root /var/www/myapp/dist;
    index index.html;

    # 5️⃣ 정적 파일 요청 처리
    location / {
        try_files $uri /index.html;
    }

 # 6️⃣ API 요청은 내부 백엔드로 프록시 전달
    location /api/ {
        proxy_pass http://192.168.10.21:8080/api/;

        # 요청 헤더 전달
        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;

        # 대용량 업로드 허용
        client_max_body_size 100M;

        # CORS (개발용, 실제 배포 시 제한 필요)
        add_header 'Access-Control-Allow-Origin' 'https://myapp.com' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type' always;

        if ($request_method = OPTIONS) {
            add_header Content-Length 0;
            add_header Content-Type text/plain;
            return 204;
        }
    }

 

즉, /api/... 요청은 nginx가 직접 처리하지 않고, 내부망의 Spring 서버로 대신 전달(리버스 프록시) 한다는 말이다.

# 7️⃣ 이미지, CSS, JS 캐싱 (브라우저 캐시 30일 유지)
    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 30d;
        add_header Cache-Control "public, no-transform";
    }

    # 8️⃣ 보안: 민감 파일 접근 차단
    location ~ /\.env { deny all; return 404; }
    location ~* \.(yml|properties|log|sql)$ { deny all; return 404; }

    # 9️⃣ 로그 (이 사이트 전용)
    access_log /var/log/nginx/myapp_access.log;
    error_log  /var/log/nginx/myapp_error.log;

 


 

nginx에서 다루는 2가지 설정파일에 대해서 다시 정리해서 비교해보자면 아래와 같다.

 

여기서 sitesenabled 폴더에 링크돼야 활성화된다는 말이 잘 와닿지 않을 것이다.

nginx는 사이트 설정 파일이 들어있는 두 폴더를 사용한다.

  • /etc/nginx/sites-available/  모든 사이트 설정 저장소 (비활성)
  • /etc/nginx/sites-enabled/  실제 동작 중인 설정 목록 (활성)

 

sites-available 폴더 안에 있는 설정파일을 nginx가 실제로 읽혀서 적용되려면 sites-enabled 폴더 안에 심볼릭 링크로 연결되어있어야한다.

(심볼릭 링크란? 원본 파일을 카리키는 바로가기 같은 것이다. 윈도우에서 파일 아이콘을 바탕화면에 바로가기 아이콘으로 만드는 것처럼 리눅스에서는 그 역할을 하는 것이 심볼릭 링크다.)

 

예를 들어, /etc/nginx/sites-available/ 안에 myapp.conf 파일이 있다고 하자.

이를 활성화시키려면 아래와 같은 명령어를 입력한다.

sudo ln -s /etc/nginx/sites-available/myapp.conf /etc/nginx/sites-enabled/

그러면 sites-enabled폴더에 바로가기 파일이 생긴다.

 

그러면, nginx가 시작 될 때 sites-enabled폴더를 자동으로 읽고 이와 연결되는 sites_available의 myapp.conf파일을 읽어 설정을 불러오게 되는 구조다.

 

(아! 항상 설정을 하고나서는 sudo systemctl restart nginx로 바뀐 설정이 적용된 nginx를 다시 시작해야할 것을 잊지 말아야한다.)