Nginx(엔진엑스)는 전 세계 웹사이트의 약 34%가 사용하는 웹서버로, Apache와 함께 가장 인기 있는 웹서버입니다. 특히 높은 동시 접속 처리 성능과 낮은 메모리 사용이 장점입니다. 이 글에서 Nginx의 기본 구조와 주요 설정을 실전 예제와 함께 설명합니다.
Nginx vs Apache
| Nginx | Apache | |
|---|---|---|
| 아키텍처 | 이벤트 기반 (비동기) | 프로세스/스레드 기반 |
| 동시 접속 | 수만 개 처리 가능 | 수천 개 수준 |
| 메모리 사용 | 적음 | 많음 |
| 정적 파일 | 매우 빠름 | 빠름 |
| 설정 방식 | 중앙 집중식 (nginx.conf) | 분산식 (.htaccess 지원) |
| 리버스 프록시 | 기본 내장, 강력 | 모듈 추가 필요 |
| 추천 상황 | 고트래픽, 워드프레스, Node.js | 공유 호스팅, .htaccess 필요 시 |
Nginx 디렉토리 구조
/etc/nginx/
├── nginx.conf # 메인 설정 파일
├── sites-available/ # 사이트별 설정 파일 (비활성 포함)
│ └── mysite # 내 사이트 설정
├── sites-enabled/ # 활성화된 사이트 (심볼릭 링크)
│ └── mysite -> ../sites-available/mysite
├── conf.d/ # 추가 설정 파일
├── snippets/ # 재사용 설정 조각
└── mime.types # MIME 타입 정의
기본 서버 블록 (가상 호스트) 설정
워드프레스 사이트를 위한 기본 Nginx 설정 예시:
server {
listen 80;
listen [::]:80;
server_name study.thisgun.net www.study.thisgun.net;
# HTTP → HTTPS 리다이렉트
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name study.thisgun.net www.study.thisgun.net;
# SSL 인증서
ssl_certificate /etc/letsencrypt/live/study.thisgun.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/study.thisgun.net/privkey.pem;
# 웹 루트 디렉토리
root /home/wpadmin/public_html;
index index.php index.html;
# 로그
access_log /var/log/nginx/study.thisgun.net.access.log;
error_log /var/log/nginx/study.thisgun.net.error.log;
# 워드프레스 퍼머링크 지원
location / {
try_files $uri $uri/ /index.php?$args;
}
# PHP 처리 (PHP-FPM)
location ~ .php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.4-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
# 정적 파일 캐시
location ~* .(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
# 보안: 숨김 파일 접근 차단
location ~ /. {
deny all;
}
# 보안: xmlrpc.php 차단
location = /xmlrpc.php {
deny all;
return 403;
}
# 파일 업로드 크기 제한
client_max_body_size 64M;
}
주요 설정 항목 설명
| 지시어 | 설명 | 예시 값 |
|---|---|---|
listen | 수신 포트 | 80 (HTTP), 443 (HTTPS) |
server_name | 도메인 이름 | study.thisgun.net |
root | 웹 파일 경로 | /home/wpadmin/public_html |
index | 기본 파일 | index.php index.html |
try_files | 파일 탐색 순서 | $uri → $uri/ → /index.php |
fastcgi_pass | PHP-FPM 연결 | unix:/var/run/php/php8.4-fpm.sock |
expires | 브라우저 캐시 기간 | 30d (30일) |
client_max_body_size | 업로드 제한 | 64M |
자주 쓰는 Nginx 명령어
# 설정 문법 검사 (변경 후 반드시!)
sudo nginx -t
# 설정 적용 (재시작 없이)
sudo systemctl reload nginx
# Nginx 재시작
sudo systemctl restart nginx
# Nginx 상태 확인
sudo systemctl status nginx
# 에러 로그 실시간 확인
sudo tail -f /var/log/nginx/error.log
# 접속 로그 실시간 확인
sudo tail -f /var/log/nginx/access.log
중요: 설정 변경 후 반드시 sudo nginx -t로 문법을 검증한 후 reload하세요. 문법 오류가 있는 상태에서 reload하면 Nginx가 멈출 수 있습니다.
성능 최적화 설정
# /etc/nginx/nginx.conf 에서
# 워커 프로세스 (CPU 코어 수에 맞추기)
worker_processes auto;
# 워커당 최대 접속 수
events {
worker_connections 1024;
}
http {
# Gzip 압축 (텍스트 파일 크기 70% 감소)
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml;
gzip_min_length 1000;
# 클라이언트 타임아웃
client_body_timeout 12;
client_header_timeout 12;
send_timeout 10;
# 버퍼 크기
client_body_buffer_size 10K;
client_header_buffer_size 1k;
}
보안 강화 설정
# server 블록 안에 추가
# 보안 헤더
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# 서버 버전 숨기기
server_tokens off;
# wp-config.php 접근 차단
location = /wp-config.php {
deny all;
}
# 업로드 폴더에서 PHP 실행 차단
location ~* /wp-content/uploads/.*.php$ {
deny all;
}
트러블슈팅
| 문제 | 원인 | 해결 |
|---|---|---|
| 403 Forbidden | 파일 권한 문제 | chmod 755 디렉토리, chmod 644 파일 |
| 502 Bad Gateway | PHP-FPM 미실행 | sudo systemctl restart php8.4-fpm |
| 413 Entity Too Large | 업로드 크기 초과 | client_max_body_size 64M; 추가 |
| 404 Not Found | try_files 미설정 | 워드프레스: try_files $uri $uri/ /index.php?$args; |
마무리
Nginx 설정의 핵심은 서버 블록 + PHP-FPM 연결 + 정적 파일 캐시 + 보안 헤더 4가지입니다. 이것만 잘 설정하면 빠르고 안전한 웹서버가 완성됩니다. 설정을 변경할 때는 항상 nginx -t → reload 순서를 지키세요.