본문으로 건너뛰기
Advertisement

실전 고수 팁 — 설정 분리 전략·리로드 원리·문법 검증 자동화

Nginx를 운영하면서 체득한 실무 노하우를 정리합니다. 설정 파일을 어떻게 구조화할지, 무중단 리로드는 어떻게 동작하는지, 그리고 자동화된 검증 파이프라인 구축법을 다룹니다.


설정 파일 분리 전략

권장 디렉터리 구조

/etc/nginx/
├── nginx.conf ← 전역 설정 (최소화)
├── conf.d/
│ ├── upstream.conf ← upstream 블록 모음
│ ├── gzip.conf ← gzip 공통 설정
│ ├── ssl-params.conf ← SSL/TLS 공통 파라미터
│ ├── proxy-params.conf ← proxy 공통 헤더 설정
│ └── security-headers.conf ← 보안 헤더 공통 설정
├── sites-available/
│ ├── example.com.conf ← 사이트별 설정 (비활성 포함)
│ └── api.example.com.conf
└── sites-enabled/
├── example.com.conf -> ../sites-available/example.com.conf
└── api.example.com.conf -> ...

nginx.conf 최소화

# /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
worker_rlimit_nofile 65535;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
worker_connections 4096;
use epoll;
multi_accept on;
}

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

sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
server_tokens off;

# 공통 설정 파일 포함
include /etc/nginx/conf.d/*.conf;

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

공통 proxy 설정 파일

# /etc/nginx/conf.d/proxy-params.conf
proxy_http_version 1.1;
proxy_set_header Connection "";
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 10s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 16k;

사이트 설정에서 include로 재사용:

# /etc/nginx/sites-enabled/example.com.conf
server {
listen 443 ssl;
server_name example.com;

location /api/ {
proxy_pass http://tomcat_backend;
include /etc/nginx/conf.d/proxy-params.conf;
}
}

무중단 리로드 원리

nginx -s reload (또는 systemctl reload nginx)를 실행하면 서비스를 중단하지 않고 설정을 적용합니다.

리로드 동작 순서

1. 관리자: nginx -s reload (또는 kill -HUP 마스터PID)

2. 마스터 프로세스가 SIGHUP 시그널 수신

3. 마스터 프로세스가 새 설정 파일 읽기 및 검증
→ 에러 있으면 리로드 중단 (기존 설정 유지)

4. 새 설정으로 새 워커 프로세스 생성 (새 연결 수락 시작)

5. 기존 워커 프로세스에 "더 이상 새 연결 받지 말라" 신호

6. 기존 워커 프로세스가 처리 중인 요청 완료 후 종료

7. 전환 완료 — 다운타임 없음
# 실전 무중단 리로드 절차
sudo nginx -t # Step 1: 문법 검증 (에러 없는지 확인)
sudo systemctl reload nginx # Step 2: 리로드 (성공 시 적용)

restart vs reload 차이:

  • restart: 마스터+워커 모두 즉시 종료 후 재시작 → 순간적인 연결 끊김 발생
  • reload: 워커만 교체, 처리 중인 요청은 기존 워커가 완료 → 다운타임 없음

문법 검증 자동화

배포 스크립트에 검증 통합

#!/bin/bash
# /usr/local/bin/nginx-deploy.sh

set -e # 에러 발생 시 즉시 중단

CONFIG_FILE="/etc/nginx/nginx.conf"

echo "=== Nginx 설정 검증 ==="
if nginx -t -c $CONFIG_FILE; then
echo "✅ 문법 검증 통과"
else
echo "❌ 문법 오류 발견 - 배포 중단"
exit 1
fi

echo "=== Nginx 리로드 ==="
systemctl reload nginx
echo "✅ Nginx 리로드 완료"

Git Hooks를 활용한 자동 검증

# .git/hooks/pre-commit
#!/bin/bash
# nginx 설정 파일이 변경된 경우 문법 검증

if git diff --cached --name-only | grep -q "nginx"; then
echo "Nginx 설정 변경 감지 — 문법 검증 중..."
docker run --rm -v $(pwd):/etc/nginx nginx nginx -t
if [ $? -ne 0 ]; then
echo "❌ Nginx 문법 오류 — 커밋 중단"
exit 1
fi
fi

GitHub Actions CI 파이프라인

# .github/workflows/nginx-check.yml
name: Nginx Config Validation

on:
pull_request:
paths:
- 'nginx/**'

jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Nginx 설정 검증
run: |
docker run --rm \
-v ${{ github.workspace }}/nginx:/etc/nginx \
nginx nginx -t

- name: 설정 출력 (디버깅용)
run: |
docker run --rm \
-v ${{ github.workspace }}/nginx:/etc/nginx \
nginx nginx -T

자주 발생하는 실수와 해결책

실수 1: add_header 상속 문제

http {
add_header X-Frame-Options SAMEORIGIN; # HTTP 레벨 설정

server {
location / {
add_header Content-Type text/html; # 이 블록에 add_header 추가하면
# X-Frame-Options가 이 location에서 사라짐!
}
}
}

해결: 한 블록 안에 모든 헤더를 함께 선언합니다.

location / {
add_header X-Frame-Options SAMEORIGIN; # 상위 것도 다시 선언
add_header Content-Type text/html;
}

또는 공통 헤더를 include로 관리:

# /etc/nginx/conf.d/security-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;

# location에서 include
location / {
include /etc/nginx/conf.d/security-headers.conf;
}

실수 2: proxy_pass 경로 슬래시 혼동

# 잘못된 예: /api/users → 백엔드 //users (슬래시 중복)
location /api {
proxy_pass http://backend/; # /api 에서 /로 교체 → //users
}

# 올바른 예
location /api/ {
proxy_pass http://backend/; # /api/ → /
}

실수 3: worker_processes와 worker_connections 미조정

# 기본값으로 방치하면 최대 동시 연결 = 1 × 1024 = 1024개
worker_processes 1; # CPU 코어 수에 맞게 조정
events {
worker_connections 1024; # 코어당 조정 필요
}

# 4코어 서버라면:
worker_processes 4;
events {
worker_connections 4096; # 총 최대 16,384 연결
}
# 또는 auto 사용
worker_processes auto;

Nginx 성능 벤치마크 도구

ab (Apache Bench)

# 100회 요청, 동시 10개
ab -n 100 -c 10 http://localhost/

# 결과 중 핵심 지표:
# Requests per second: 초당 처리 요청 수
# Time per request: 요청당 평균 응답 시간 (ms)
# Failed requests: 실패 요청 수

wrk

# 30초 동안 4스레드 100 연결
wrk -t4 -c100 -d30s http://localhost/api/test

# 결과:
# Requests/sec: 초당 처리량
# Latency: 지연시간 분포 (avg, stdev, max, 99%)

정리

주제핵심 포인트
설정 분리nginx.conf 최소화 + conf.d에 역할별 파일 분리
공통 설정proxy-params.conf, security-headers.conf로 재사용
무중단 리로드nginx -t 검증 후 systemctl reload (restart 사용 금지)
CI 자동화Git hooks 또는 GitHub Actions에서 nginx -t 자동 실행
헤더 상속add_header는 블록 내에서 모두 재선언 또는 include 사용
Advertisement