Nginx
NGINX란?
[!WARNING] Ubuntu의 기본 패키지 저장소에 있는 nginx는 매우 오래된 버전(1.18.0)입니다. 최신 기능과 보안 업데이트를 위해 공식 NGINX 리포지토리를 설정하여 설치하는 것을 강력히 권장합니다.
NGINX는 고성능의 리버스 프록시(Reverse Proxy), 로드 밸런서(Load Balancer), 그리고 웹 서버입니다. 적은 리소스로 많은 트래픽을 처리할 수 있는 효율성 덕분에 전 세계 수많은 대규모 웹사이트에서 사용되고 있습니다.
1. Nginx 설치하기
먼저 패키지 목록을 업데이트하고 Nginx를 설치합니다.
sudo apt update
sudo apt install nginx⚠️ 공식 NGINX 리포지토리 설정 방법
공식 최신 버전을 설치하려면 터미널에서 다음 명령어들을 순서대로 입력해야 합니다.
-
패키지 인덱스 업데이트:
sudo apt update -
필수 패키지 설치:
sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring -
NGINX GPG 키 추가:
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null -
공식 리포지토리 추가:
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \ http://nginx.org/packages/ubuntu/ $(lsb_release -cs) nginx" \ | sudo tee /etc/apt/sources.list.d/nginx.list -
패키지 인덱스 다시 업데이트:
sudo apt update -
NGINX 설치:
sudo apt install nginx
2. 설치 확인
설치가 완료되면 서비스가 자동으로 실행됩니다. 설치가 완료되었는지 확인합니다.
# NGINX 버전 확인
sudo nginx -v
# NGINX 상태 확인
sudo systemctl status nginx웹 브라우저에서 http://localhost로 접속하여 NGINX의 기본 환영 페이지가 뜨는지 확인합니다.
3. 방화벽 설정 (UFW)
외부에서 웹 서버에 접속할 수 있도록 포트를 열어줘야 합니다. 보통 HTTP(80)와 HTTPS(443)를 모두 허용하는 'Nginx Full' 프로필을 사용합니다.
sudo ufw allow 'OpenSSH'
sudo ufw allow 'Nginx Full' # 또는 'Nginx HTTP', 'Nginx HTTPS' 별도 허용4. 기본 설정 및 가상 호스트(Server Block) 구성
Nginx의 설정 파일 구조는 다소 독특합니다. 여러 사이트를 운영할 계획이라면 아래 방식을 따르는 것이 정석입니다.
- 설정 파일 위치:
/etc/nginx/sites-available/ - 활성화 링크 위치:
/etc/nginx/sites-enabled/
예시: 내 도메인 설정하기
example.com이라는 설정을 만든다고 가정해 보겠습니다.
-
설정 파일 생성
sudo nano /etc/nginx/sites-available/example.com -
내용 작성 (가장 기본적인 설정입니다)
server { listen 80; server_name example.com www.example.com; root /var/www/html; index index.html; location / { try_files $uri $uri/ =404; } } -
설정 활성화 (심볼릭 링크) 작성한 설정을 Nginx가 읽을 수 있도록 연결해 줍니다.
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
5. 설정 검사 및 재시작
설정 파일에 오타가 있으면 서버가 멈출 수 있습니다. 반드시 문법 검사를 먼저 하세요.
sudo nginx -tsyntax is ok 메시지가 나오면 서비스를 재시작하여 변경 사항을 적용합니다.
sudo systemctl restart nginx💡 주요 디렉토리 요약
| 경로 | 설명 |
|---|---|
/etc/nginx/nginx.conf | 기본 메인 설정 파일 |
/etc/nginx/sites-available/ | 개별 사이트 설정 파일 보관소 |
/etc/nginx/sites-enabled/ | 실제로 활성화된 사이트 링크 |
/etc/nginx/conf.d/ | 실제 웹사이트 설정 파일(서버 블록) |
/var/log/nginx/ | 에러 로그와 액세스 로그 |
/var/log/nginx/access.log | 접속 기록 로그 |
/var/log/nginx/error.log | 오류 기록 로그 |
홈네트워크
홈 네트워크 환경에서 Nginx를 운영할 때는 공인 도메인이 없는 경우가 많죠. 이럴 때 server_name에 사용할 수 있는 옵션은 크게 세 가지입니다.
1. IP 주소 사용 (가장 일반적)
별도의 도메인 설정 없이 내부망 IP나 외부 공인 IP로 접속할 때 사용합니다.
- 설정:
server_name 192.168.0.10;(본인 서버의 내부 IP) - 특징: 가장 확실하고 단순합니다. IP 주소로 들어오는 요청만 처리하겠다는 뜻입니다.
2. 와일드카드 또는 언더스코어 (_)
어떤 이름으로 들어오든 이 서버 블록에서 처리하도록 하는 설정입니다. 홈 서버에서 하나의 서비스만 운영할 때 편리합니다.
- 설정:
server_name _; - 특징: "이 서버로 들어오는 모든 요청(IP, 호스트명 등)을 다 받아라"라는 의미의 Catch-all 설정입니다.
3. 로컬 호스트명 (mDNS)
공유기 설정이나 PC 이름에 따라 .local 주소를 사용할 수 있습니다.
- 설정:
server_name my-server.local; - 특징: 같은 네트워크에 있는 기기들이
[http://my-server.local](http://my-server.local)로 접속할 수 있게 해줍니다. (단, 기기들이 mDNS를 지원해야 함)
💡 추천하는 설정 방식
만약 내부망에서 여러 개의 웹 서비스를 돌리고 싶다면(예: 하나는 대시보드, 하나는 파일 서버), 다음과 같이 설정하는 것이 관리가 편합니다.
# 1번 서비스 (대시보드)
server {
listen 80;
server_name 192.168.0.10; # 서버 IP로 접속 시
root /var/www/dashboard;
}
# 2번 서비스 (나중에 도메인을 연결할 계획이라면)
server {
listen 80;
server_name myhome.duckdns.org; # DDNS 주소 사용
root /var/www/mysite;
}요약 가이드
- 테스트용/단일 서비스:
server_name _;또는server_name 내부IP; - 외부에서도 접속할 경우: DuckDNS 같은 무료 DDNS 서비스를 가입한 뒤, 그 주소를
server_name에 적어주세요. (예:example.duckdns.org)
Nginx 핵심 설정 매뉴얼
Nginx는 가볍고 강력한 성능 덕분에 현대 웹 아키텍처에서 가장 많이 사용되는 웹 서버이자 리버스 프록시입니다. 초보자부터 실무자까지 참고할 수 있는 Nginx 핵심 설정 매뉴얼을 정리해 드립니다.
1. Nginx 기본 구조와 파일 위치
Nginx 설정은 계층 구조로 이루어져 있으며, 설정 파일들은 보통 /etc/nginx/ 디렉토리에 위치합니다.
/etc/nginx/nginx.conf: 메인 설정 파일. 전체적인 프로세스 운영 방식 설정./etc/nginx/sites-available/: 개별 사이트(도메인) 설정 파일들이 보관되는 곳./etc/nginx/sites-enabled/: 실제로 활성화된 사이트 설정.sites-available에 있는 파일을 심볼릭 링크로 연결하여 사용합니다.
2. 설정 파일의 계층 구조 (Context)
Nginx 설정은 블록({ })으로 구분되며, 상위 설정이 하위로 상속됩니다.
- Main: 전역 설정 (프로세스 수, 로그 경로 등)
- Events: 네트워크 연결 처리 방식 (최대 접속자 수 등)
- HTTP: 웹 트래픽 처리 관련 공통 설정
- Server: 특정 도메인(Virtual Host) 설정
- Location: 도메인 내 특정 경로(URL) 처리 규칙
3. 핵심 블록별 상세 설명
🟢 Server 블록 (가상 호스트)
하나의 서버에서 여러 도메인을 운영할 때 사용합니다.
server {
listen 80; # IPv4에서 80포트 접속 허용
listen [::]:80; # IPv6에서 80포트 접속 허용
server_name example.com; # 서비스할 도메인 이름
root /var/www/html; # 웹 파일이 위치한 경로
index index.html; # 기본 문서 이름
}🔵 Location 블록 (경로 제어)
URL 경로에 따라 다른 처리를 하고 싶을 때 사용합니다.
location / {
# 기본 경로 처리
}
location /images/ {
# 이미지 파일 경로 설정
root /data;
}
location ~* \.(jpg|png|gif)$ {
# 정규표현식을 사용한 이미지 파일 캐싱 설정
expires 30d;
}🟡 Reverse Proxy (프록시 설정)
가장 많이 사용하는 기능으로, 외부 요청을 내부 서버(Node.js, Python 등)로 전달합니다.
location /api/ {
proxy_pass http://localhost:3000; # 내부 서버 포트로 전달
proxy_set_header Host $host; # 원본 호스트 정보 유지
proxy_set_header X-Real-IP $remote_addr; # 실제 접속자 IP 전달
}4. 보안 및 성능 최적화 설정
HTTPS 설정 (SSL)
certbot 등을 통해 받은 인증서를 적용하는 표준 방식입니다.
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
# 보안 강화를 위한 프로토콜 설정
ssl_protocols TLSv1.2 TLSv1.3;
}리다이렉션 (HTTP -> HTTPS)
모든 비암호화 요청을 안전한 HTTPS로 강제 이동시킵니다.
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}Gzip 압축 (성능 향상)
텍스트 파일 등을 압축해서 전송하여 로딩 속도를 높입니다.
gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_min_length 1000;5. 자주 쓰는 관리 명령어
| 명령어 | 설명 |
|---|---|
sudo nginx -t | 필수! 설정 파일에 오타가 없는지 검사 |
sudo systemctl reload nginx | 다운타임 없이 설정 변경 사항만 반영 |
sudo systemctl restart nginx | Nginx 프로세스를 완전히 재시작 |
tail -f /var/log/nginx/error.log | 실시간 에러 로그 모니터링 |
💡 마지막 팁
Nginx를 수정할 때는 반드시 nginx -t로 문법 검사를 먼저 하세요. 문법이 틀린 상태에서 재시작하면 서비스가 즉시 중단될 수 있습니다.
심화 기능
심화 기능 중에서 가장 실무 활용도가 높은 **로드 밸런싱(Load Balancing)**과 캐싱(Caching), 그리고 보안을 위한 Rate Limiting 설정을 추가로 설명해 드릴게요.
1. 로드 밸런싱 (Load Balancing)
여러 대의 서버로 트래픽을 분산시켜 서버 부하를 줄이고 가용성을 높이는 기능입니다. upstream 블록을 사용합니다.
upstream my_backend {
# least_conn; # 접속 수가 가장 적은 서버로 전달 (옵션)
server 127.0.0.1:3001; # 서버 1
server 127.0.0.1:3002; # 서버 2
server 127.0.0.1:3003 backup; # 다른 서버 다운 시 가동되는 백업 서버
}
server {
listen 80;
location / {
proxy_pass http://my_backend;
}
}2. 정적 파일 캐싱 (Caching)
서버의 응답을 Nginx가 일시적으로 저장하여, 동일한 요청이 올 때 백언드 서버(Node.js 등)를 거치지 않고 바로 응답하는 기능입니다. 서버 자원을 극적으로 아낄 수 있습니다.
- 설정 예시:
# 캐시 저장 경로와 용량 설정 (http 블록 안에 작성) proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g; server { location / { proxy_cache my_cache; # 위에서 설정한 존(zone) 사용 proxy_cache_valid 200 60m; # 200 응답은 60분간 캐싱 proxy_pass http://localhost:3001; } }
3. 접속 제한 (Rate Limiting)
DDoS 공격을 방지하거나 특정 사용자가 과도하게 API를 호출하는 것을 막기 위해 초당 요청 횟수를 제한합니다.
# IP당 초당 5번의 요청만 허용 (http 블록)
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=5r/s;
server {
location /api/ {
# 제한을 초과하면 503 에러 반환, 갑작스런 버스트는 10개까지 허용
limit_req zone=mylimit burst=10 nodelay;
proxy_pass http://localhost:3001;
}
}4. 실전 팁: 무중단 배포를 위한 설정
새로운 코드를 배포할 때 Nginx는 매우 유용합니다.
- Blue-Green 배포: 3001번(기존)에서 3002번(신규)으로 서버를 띄운 뒤, Nginx 설정의
proxy_pass포트만 변경하고nginx -s reload를 실행하면 접속 끊김 없이 배포가 완료됩니다. - Health Check:
upstream설정 시max_fails와fail_timeout을 사용하면 특정 서버가 응답하지 않을 때 자동으로 목록에서 제외할 수 있습니다.
📋 Nginx 설정 확인 절차 (체크리스트)
수정 후엔 항상 이 순서를 따르세요:
sudo nginx -t: "syntax is ok" 확인.sudo systemctl reload nginx: 실제 반영.curl -I [https://your-domain.com](https://your-domain.com): 응답 헤더가200 OK인지 확인.
프록시 심화
Nginx의 핵심 기능인 프록시(Proxy) 설정에 대해 깊게 들어가 보겠습니다. Nginx는 클라이언트와 서버 사이에서 중재자 역할을 하며 보안, 성능, 유연성을 제공합니다.
1. 리버스 프록시의 기본 구조
클라이언트가 Nginx에 요청을 보내면, Nginx는 그 요청을 내부 서버(Node.js, Go, Python 등)로 전달하고 결과를 받아 다시 클라이언트에게 보내줍니다.
핵심 지시어: proxy_pass
가장 중요한 설정입니다. 요청을 보낼 목적지 주소를 지정합니다.
proxy_pass http://localhost:3000;: 로컬 3000번 포트로 전달.proxy_pass http://unix:/tmp/backend.socket;: 유닉스 소켓을 통해 전달 (속도가 더 빠름).
2. 프록시 헤더 설정 (중요)
프록시를 거치면 백엔드 서버는 클라이언트의 실제 정보를 잃어버리게 됩니다. 이를 방지하기 위해 헤더를 수동으로 넘겨줘야 합니다.
location / {
proxy_pass http://localhost:3000;
# 1. 원래 요청의 호스트 이름을 유지 (예: gnbiz.mywire.org)
proxy_set_header Host $host;
# 2. 클라이언트의 실제 IP 주소를 전달
proxy_set_header X-Real-IP $remote_addr;
# 3. 경유한 모든 프록시 IP 이력을 전달
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 4. 클라이언트가 사용한 프로토콜(http 또는 https)을 전달
# 이 설정이 없으면 백엔드에서 HTTPS 접속 여부를 몰라 무한 리다이렉트가 발생할 수 있음
proxy_set_header X-Forwarded-Proto $scheme;
}3. 타임아웃 및 버퍼 설정 (안정성)
백엔드 서버가 응답이 늦거나 데이터가 클 때를 대비한 설정입니다.
타임아웃 (Timeout)
proxy_connect_timeout: Nginx가 백엔드 서버에 연결을 시도하는 시간 (기본 60초).proxy_read_timeout: 연결 후 응답을 기다리는 시간. API가 무겁다면 이 값을 늘려야 합니다.proxy_send_timeout: 백엔드로 데이터를 보낼 때의 제한 시간.
버퍼 (Buffering)
Nginx는 백엔드의 응답을 메모리에 모았다가 클라이언트에게 보냅니다.
proxy_buffering on;: 응답 속도가 다른 클라이언트를 위해 켜두는 것이 권장됩니다.proxy_buffer_size: 헤더를 담는 버퍼 크기.proxy_buffers: 본문을 담는 버퍼의 개수와 크기.
4. WebSocket 프록시 설정
Better Auth나 실시간 채팅 기능을 사용할 때 WebSocket이 필요하다면 아래 설정을 반드시 추가해야 합니다. 일반적인 HTTP 요청과는 헤더 처리 방식이 다르기 때문입니다.
location /socket.io/ {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
# WebSocket 연결을 위한 업그레이드 헤더
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}5. 프록시 에러 처리
백엔드 서버가 죽었을 때 사용자에게 깔끔한 에러 페이지를 보여주고 싶다면 사용합니다.
location / {
proxy_pass http://localhost:3000;
# 백엔드 서버에서 404나 500번대 에러가 나면 Nginx가 가로챔
proxy_intercept_errors on;
error_page 500 502 503 504 /custom_50x.html;
}
location = /custom_50x.html {
root /usr/share/nginx/html;
}💡 요약: "이것만은 꼭 넣어라"
운영 중인 서비스의 안정성을 위해 최소한 아래 3개는 프록시 설정에 포함하는 것이 좋습니다.
X-Forwarded-Proto $scheme: HTTPS 관련 인증 문제 방지.X-Real-IP $remote_addr: 로그에 사용자 실제 IP 기록.client_max_body_size: 파일 업로드 용량 제한 해제.