Nginx는 단순한 웹 서버를 넘어 현대 웹 인프라의 핵심 구성 요소로 자리잡았습니다. 본 가이드는 실제 구축 순서에 따라 필수 기본 설정부터 고급 최적화까지 단계적으로 진행하여, 실무에서 바로 적용할 수 있는 체계적인 Nginx 설정 방법을 제시합니다.
1단계: 기본 구조 설계 및 필수 설정
디렉토리 구조 설계
Nginx 설정의 첫 번째 단계는 체계적인 파일 구조를 설계하는 것입니다:
/etc/nginx/
├── nginx.conf # 메인 설정 파일 (가장 중요)
├── conf.d/ # 사이트별 설정
├── snippets/ # 재사용 가능한 설정 조각
├── upstream/ # 백엔드 서버 정의
├── security/ # 보안 설정
├── performance/ # 성능 최적화
├── monitoring/ # 로깅 & 모니터링
└── scripts/ # 관리 스크립트
핵심 메인 설정 (nginx.conf)
모든 Nginx 설정의 기초가 되는 메인 설정파일부터 시작합니다. 단계별로 필요한 설정들을 import하는 구조로 구성합니다:
# nginx.conf - 단계별 설정 import 구조
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
# 기본 보안 설정
worker_rlimit_nofile 65535;
events {
worker_connections 1024; # 기본값, 나중에 최적화
use epoll;
multi_accept on;
}
http {
# 1단계: 기본 필수 설정
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 2단계: 로그 형식 정의 (기본 → 확장)
include /etc/nginx/monitoring/log-formats.conf;
# 3단계: 맵 정의들 (조건부 처리용)
include /etc/nginx/maps/*.conf;
# 4단계: 기본 성능 설정
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
# 5단계: 성능 최적화 설정 (단계적 적용)
include /etc/nginx/performance/compression.conf;
include /etc/nginx/performance/file-cache.conf;
# include /etc/nginx/performance/optimization.conf; # 6단계에서 주석 해제
# 6단계: 보안 설정 (기본 → 고급)
server_tokens off;
include /etc/nginx/security/basic-headers.conf;
include /etc/nginx/security/basic-access.conf;
# include /etc/nginx/security/rate-limiting.conf; # 7단계에서 주석 해제
# include /etc/nginx/security/csp.conf; # 7단계에서 주석 해제
# 7단계: 업스트림 서버 정의 (백엔드 연동 시)
include /etc/nginx/upstream/*.conf;
# 8단계: 캐싱 설정 (필요 시)
# include /etc/nginx/performance/proxy-cache.conf; # 9단계에서 주석 해제
# 9단계: 모니터링 설정
# include /etc/nginx/monitoring/status.conf; # 운영 시 주석 해제
# 최종: 사이트별 설정 로드 (항상 마지막)
include /etc/nginx/conf.d/*.conf;
}
첫 번째 가상 호스트 설정
기본적인 사이트 설정으로 시작합니다:
# conf.d/example.com.conf - 기본 사이트 설정
server {
listen 80;
server_name example.com www.example.com;
# 기본 보안 설정
client_max_body_size 10M;
# 문서 루트
root /var/www/example.com;
index index.html index.htm;
# 기본 로깅
access_log /var/log/nginx/example.com.access.log main;
error_log /var/log/nginx/example.com.error.log;
# 기본 위치 블록
location / {
try_files $uri $uri/ =404;
}
# 정적 파일 기본 캐싱
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1d;
add_header Cache-Control "public";
}
}
2단계: 필수 보안 설정 적용
기본 구조가 완성되면 보안 설정을 적용합니다.
기본 보안 헤더 설정
# security/basic-headers.conf
# 기본적으로 모든 사이트에 적용할 보안 헤더
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# 서버 정보 숨김
server_tokens off;
기본 접근 제어
# security/basic-access.conf
# 위험한 파일들에 대한 기본 접근 차단
# 숨김 파일 차단
location ~ /\. {
deny all;
access_log off;
}
# 백업 파일 차단
location ~* \.(bak|backup|old|tmp)$ {
deny all;
}
메인 설정에 보안 설정 포함
# nginx.conf에 추가
http {
# ... 기존 설정들 ...
# 기본 보안 설정 포함
include /etc/nginx/security/basic-headers.conf;
include /etc/nginx/security/basic-access.conf;
# ... 나머지 설정들 ...
}
3단계: SSL/HTTPS 설정 (필수)
현재 모든 웹사이트는 HTTPS가 필수이므로 SSL 설정을 진행합니다.
기본 SSL 설정
# snippets/ssl-params.conf
# 재사용 가능한 SSL 설정
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
HTTPS 사이트 설정으로 업그레이드
# conf.d/example.com.conf - HTTPS로 업그레이드
server {
listen 80;
server_name example.com www.example.com;
# HTTPS로 리디렉션
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# SSL 인증서
ssl_certificate /etc/nginx/certs/example.com/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/example.com/privkey.pem;
# SSL 설정 포함
include /etc/nginx/snippets/ssl-params.conf;
# HSTS 헤더 추가
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# 기존 설정들...
root /var/www/example.com;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
4단계: 백엔드 연동 (업스트림 설정)
정적 사이트에서 동적 애플리케이션으로 발전시킬 때 업스트림을 설정합니다.
기본 업스트림 정의
# upstream/backend-servers.conf
# 백엔드 서버 그룹 정의
upstream app_backend {
server 127.0.0.1:3000; # 단일 서버로 시작
keepalive 32;
}
프록시 설정 추가
# snippets/proxy-params.conf
# 기본 프록시 설정
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;
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
사이트 설정에 프록시 적용
# conf.d/example.com.conf에 추가
server {
# ... SSL 설정들 ...
# 정적 파일은 직접 제공
location /static/ {
root /var/www/example.com;
expires 1M;
}
# 동적 요청은 백엔드로 프록시
location / {
proxy_pass http://app_backend;
include /etc/nginx/snippets/proxy-params.conf;
}
}
5단계: 기본 성능 최적화
기본 기능이 동작하면 성능 최적화를 진행합니다.
워커 프로세스 최적화
# nginx.conf 업데이트
worker_processes auto;
worker_rlimit_nofile 65535;
events {
worker_connections 4096; # 기본 1024에서 증가
use epoll;
multi_accept on;
accept_mutex off;
}
기본 압축 설정
# performance/compression.conf
# 기본 Gzip 압축
gzip on;
gzip_min_length 1024;
gzip_comp_level 6;
gzip_types
text/plain
text/css
application/json
application/javascript
text/xml
application/xml;
파일 캐시 최적화
# performance/file-cache.conf
# 파일 디스크립터 캐시
open_file_cache max=10000 inactive=60s;
open_file_cache_valid 120s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
6단계: 로깅 및 모니터링 구성
운영을 위한 로깅과 모니터링을 설정합니다.
확장된 로그 형식
# monitoring/log-formats.conf
log_format main_extended '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time uct="$upstream_connect_time" '
'urt="$upstream_response_time"';
상태 모니터링
# monitoring/status.conf
location /nginx_status {
stub_status;
allow 127.0.0.1;
allow 10.0.0.0/8;
deny all;
access_log off;
}
7단계: 고급 보안 설정
기본 운영이 안정되면 고급 보안 기능을 추가합니다.
Rate Limiting 구현
# security/rate-limiting.conf
# DDoS 및 브루트포스 공격 방어
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
# 사이트 설정에 적용
location / {
limit_req zone=general burst=20 nodelay;
proxy_pass http://app_backend;
}
location /login {
limit_req zone=login burst=5 nodelay;
proxy_pass http://app_backend;
}
Content Security Policy
# security/csp.conf
# XSS 공격 방어를 위한 CSP
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'" always;
지역 기반 접근 제어
# security/geo-blocking.conf
# GeoIP2를 이용한 국가별 차단 (선택사항)
geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {
$geoip2_country_code country iso_code;
}
map $geoip2_country_code $blocked_country {
default 0;
CN 1;
RU 1;
}
8단계: 로드밸런싱 및 고가용성
트래픽 증가에 대비한 로드밸런싱을 구성합니다.
다중 백엔드 서버 설정
# upstream/backend-servers.conf 업데이트
upstream app_backend {
least_conn; # 연결 수 기반 로드밸런싱
server 127.0.0.1:3000 weight=3;
server 127.0.0.1:3001 weight=2;
server 127.0.0.1:3002 weight=1 backup;
keepalive 32;
}
헬스체크 설정
# 기본 헬스체크 (Nginx Plus 없이)
upstream app_backend {
server 127.0.0.1:3000 max_fails=3 fail_timeout=30s;
server 127.0.0.1:3001 max_fails=3 fail_timeout=30s;
}
9단계: 캐싱 전략 구현
성능 향상을 위한 다층 캐싱을 구현합니다.
프록시 캐시 설정
# performance/proxy-cache.conf
proxy_cache_path /var/cache/nginx/main
levels=1:2
keys_zone=main_cache:100m
inactive=60m
max_size=1g;
# 사이트 설정에 적용
location / {
proxy_cache main_cache;
proxy_cache_valid 200 302 5m;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error timeout updating;
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://app_backend;
}
정적 파일 캐싱 최적화
# 정적 파일별 세분화된 캐싱
location ~* \.(jpg|jpeg|png|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
add_header Vary "Accept-Encoding";
}
location ~* \.(css|js)$ {
expires 1M;
add_header Cache-Control "public";
add_header Vary "Accept-Encoding";
}
10단계: 고급 기능 및 특수 요구사항
마지막으로 특수한 요구사항에 맞는 고급 기능을 구현합니다.
WebSocket 지원
# proxy/websocket.conf
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
location /ws {
proxy_pass http://app_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
API 게이트웨이 기능
# 마이크로서비스 라우팅
location /api/users/ {
limit_req zone=api burst=50 nodelay;
proxy_pass http://user_service;
}
location /api/orders/ {
limit_req zone=api burst=30 nodelay;
proxy_pass http://order_service;
}
이미지 최적화
# media/image-processing.conf
location ~ ^/images/resize/(\d+)x(\d+)/(.+)$ {
image_filter resize $1 $2;
image_filter_jpeg_quality 85;
root /var/www/images;
expires 1M;
}
설정 검증 및 배포 스크립트
자동화된 검증 스크립트
#!/bin/bash
# scripts/deploy-config.sh
# 설정 배포 전 검증
echo "1. 설정 문법 검사..."
nginx -t
if [ $? -ne 0 ]; then
echo "설정 오류 발견. 배포 중단."
exit 1
fi
echo "2. SSL 인증서 확인..."
for cert in /etc/nginx/certs/*/fullchain.pem; do
if [ -f "$cert" ]; then
openssl x509 -in "$cert" -noout -checkend 2592000
fi
done
echo "3. 백업 생성..."
tar -czf "/backup/nginx-$(date +%Y%m%d-%H%M%S).tar.gz" /etc/nginx/
echo "4. 설정 리로드..."
nginx -s reload
echo "배포 완료!"
결론
Nginx 설정은 단계적으로 접근하는 것이 핵심입니다. 기본 구조와 필수 보안 설정부터 시작하여, 점진적으로 성능 최적화와 고급 기능을 추가해나가는 것이 안정적이고 관리하기 쉬운 인프라를 구축하는 방법입니다.
각 단계에서 충분한 테스트를 거치고, 다음 단계로 넘어가기 전에 현재 설정이 안정적으로 동작하는지 확인하는 것이 중요합니다. 또한 설정의 변경사항을 버전 관리 시스템을 통해 추적하고, 정기적인 백업을 통해 장애에 대비하는 것도 필수적입니다.