우선 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 시스템콜 사용
'Server > Nginx' 카테고리의 다른 글
| 🖇️ Nginx Upstream을 사용하여 서버 이중화 설정하기 (0) | 2026.07.04 |
|---|---|
| 🎯 nginx 동적모듈(dynamic module) 빌드해서 적용하기 (0) | 2026.01.25 |