우선 Nginx 설정 파일은 크게 2가지로 나뉜다.
구조를 나눔으로써 운영 영향도를 줄이고 설정 충돌 방지, 서비스 추가/삭제가 쉬우며 롤백이 쉽다.
 

nginx 설정 구조

/etc/nginx/
├── nginx.conf          # 메인 설정 파일
├── conf.d/                # 서버별 설정 include
│   ├── default.conf
│   └── api.conf
│   └── web.conf
 
 

수정 시 영향도 확인

  • nginx.conf 수정 → nginx 전체 영향
  • conf.d/*.conf 수정 → 해당 서비스만 영향

 
 

1. 메인 설정 (Main Config) - /etc/nginx/nginx.conf 

-> nginx 전체 프로세스/동작 방식을 정의하는 루트 설정
 
1-1. 전역(Global) 설정

user  nginx;
worker_processes  auto;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

 

  • user : nginx 프로세스 실행 계정
  • worker_processes : 워커 프로세스 개수
  • error_log : 에러 로그
  • pid : PID 파일

2-2. 이벤트 블록
동시에 처리 가능한 커넥션 수

events {
    worker_connections  1024;
}

 
2-3. http 블록
HTTP 서버 전역 설정

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

    log_format main '$remote_addr - $remote_user ...';
    access_log /var/log/nginx/access.log main;

    sendfile        on;
    keepalive_timeout 65;

    include /etc/nginx/conf.d/*.conf; //서비스 설정파일 include
    
    map $http_upgrade $connection_upgrade {
    default upgrade;   # 1순위: 아무것도 매칭 안 되면 이거
    '' close;          # 2순위: 빈 문자열이면 이거
    }
}
  • MIME 타입
  • 로그 포맷
  • gzip
  • proxy 관련 기본값
  • SSL 기본값
  • upstream 정의 가능
  • 중요! 서비스별 설정을 직접 다 넣기보다는 include 로 분리하는 구조

 

트러블슈팅

  일반 HTTP WebSocket
연결요청할 때마다 새로 연결한 번 연결하면 계속 유지
방향클라이언트 → 서버 (단방향)양방향 자유롭게
사용 예웹페이지, REST API, 이미지 로딩채팅, 알림, 게임, 실시간 데이터

 
만약에 WebSoket을 사용하는 시스템이라면 서비스 설정 파일 안에 해당 Proxy header가 들어있을것이다.

       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection $connection_upgrade;

 
그렇다면 메인 설정 파일의 http 블록 안에 아래 코드가 들어가야하며 그렇지 않으면 오류 발생한다.

    map $http_upgrade $connection_upgrade {
    default upgrade;   # 1순위: 아무것도 매칭 안 되거나 빈 문자열이 아니면 이거
    '' close;          # 2순위: 빈 문자열이면 이거
    }

 
케이스 1: WebSocket 요청

  • $http_upgrade = "websocket" (Upgrade 헤더 값)
  • 매칭 확인:
    • close 매칭 ❌ (빈 문자열 아님)
    • default upgrade 매칭 ⭕
  • 결과: $connection_upgrade = "upgrade"

케이스 2: 일반 HTTP 요청

  • $http_upgrade = "" (빈 문자열, Upgrade 헤더 없음)
  • 매칭 학인:
    • close 매칭 ⭕ (여기서 끝!)
  • 결과: $connection_upgrade = "close"
  • default는 확인조차 안 함

케이스 3: 이상한 값이 들어온 경우

  • $http_upgrade = "something-weird"
  • 매칭 확인:
    • close 매칭 ❌ (빈 문자열 아님)
    • default upgrade 매칭 ⭕
  • 결과: $connection_upgrade = "upgrade"

 

2. 서비스 설정 (Service / Virtual Host) - /etc/nginx/conf.d/*.conf

HTTPS + WebSocket 예시
아래 코드는 nginx를 proxy server로 사용한 예시이다.

server {
    listen 443 ssl;
    server_name chat.example.com;
    
    # SSL 해독처리로 HTTPS 여기서 처리!
    ssl_certificate /etc/nginx/ssl/cert.pem;
    ssl_certificate_key /etc/nginx/ssl/key.pem;
    
    location / {
        proxy_pass http://localhost:8080; # proxy server
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade; # HTTP/WebSocket 처리
        proxy_set_header Connection $connection_upgrade; # HTTP/WebSocket 처리
        proxy_set_header Host $host;
    }
}

 
 

1. HTTPS 요청 (일반 웹페이지)

브라우저 → https://chat.example.com (443 포트)
         → nginx (SSL 해독)
         → http://localhost:8080 (평문 HTTP로 전달)

 

2. WebSocket 연결 (wss://)

브라우저 → wss://chat.example.com (443 포트)
         → nginx (SSL 해독 + WebSocket 업그레이드)
         → ws://localhost:8080 (평문 WebSocket으로 전달)

 

Proxy Server란 뭘까?

-> 중간 다리 역할을 해주는 서버이다.
-> Apache (with mod_proxy), Caddy, Envoy 같은 Proxy Server가 존재한다.
 
사용자 브라우저 → nginx (80포트) → Node.js 앱 (3000포트)
 
사용자는 80, 443 인터넷 포트만 알고 접속하면 알아서 여러 서버의 포트로 연결시켜준다.
 

  • 보안: 실제 서버(3000포트) 직접 노출 안 함
  • 로드밸런싱: 여러 서버에 트래픽 분산
  • SSL 처리: nginx가 HTTPS 처리, 앱은 HTTP만
  • 정적 파일: 이미지 같은 건 nginx가 직접 서빙

왜 nginx가 정적 파일 서빙에 빠를까?

-> 이미지 요청 → nginx가 디스크에서 바로 읽어서 전송하기 때문!
 

  • 엄청 빠름: C로 작성됨, 파일 읽기에 최적화
  • 백엔드 부하 감소: Node.js가 파일 처리 안 해도 됨 ( 이미지 요청 → nginx → Node.js → 파일 읽기 → nginx → 브라우저 ) 
  • 효율적 메모리: 파일 캐싱, sendfile 시스템콜 사용

 
 

+ Recent posts