Nginx 기본 설정 파일 구조 이해하기
Nginx를 설치하고 나면 가장 먼저 마주하는 게 설정 파일입니다. 브라우저에서 접속했을 때 어떤 파일을 보여줄지, 어떤 포트에서 요청을 받을지, SSL은 어떻게 처리할지 전부 이 설정 파일에서 결정됩니다. 그런데 처음 파일을 열어보면 중괄호가 겹겹이 들어가 있고 낯선 지시어들이 나열되어 있어서 어디를 어떻게 건드려야 하는지 감이 안 옵니다. 이번 글에서는 Nginx 설정 파일의 전체 구조를 잡아주고, 각 블록이 무슨 역할을 하는지 실제 파일을 보면서 정리해보겠습니다.
설정 파일 위치부터 확인하기
Ubuntu 기준으로 Nginx를 설치하면 설정 파일들이 /etc/nginx/ 디렉토리에 생깁니다. 터미널에서 이 디렉토리를 열어보면 여러 파일과 폴더가 보입니다.
ls /etc/nginx/
여기서 중요한 것들만 추리면 이렇습니다.
nginx.conf가 메인 설정 파일입니다. Nginx가 실행될 때 가장 먼저 읽는 파일이고, 전체 동작의 뼈대가 여기에 정의되어 있습니다.
sites-available 폴더에는 사이트별 설정 파일을 만들어둡니다. 예를 들어 today-play.com 설정 파일을 여기에 작성합니다.
sites-enabled 폴더에는 실제로 활성화할 사이트의 심볼릭 링크를 넣습니다. sites-available에 파일을 만들었다고 바로 적용되는 게 아니라, sites-enabled에 링크를 걸어야 Nginx가 인식합니다.
conf.d 폴더도 있는데, 이건 sites-available/sites-enabled 구조 대신 사용할 수 있는 대안입니다. 이 폴더에 .conf 확장자로 파일을 넣으면 자동으로 로드됩니다. 배포판에 따라 둘 중 하나만 사용하는 경우도 있습니다.
mime.types 파일은 파일 확장자와 Content-Type을 매핑하는 파일입니다. .html 파일을 요청하면 text/html로 응답하고, .jpg 파일을 요청하면 image/jpeg로 응답하는 게 이 파일 덕분입니다. 보통 건드릴 일이 없습니다.
nginx.conf 파일 열어보기
핵심은 nginx.conf입니다. 이 파일을 열어보면 대략 이런 구조로 되어 있습니다.
user www-data;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
처음 보면 복잡해 보이지만 크게 세 부분으로 나뉩니다. 최상위 컨텍스트, events 블록, http 블록입니다. Nginx 설정은 이 블록 구조를 이해하는 게 전부라고 해도 과언이 아닙니다.
최상위 컨텍스트
파일 맨 위에 있는 부분으로, 어떤 블록에도 속하지 않는 지시어들입니다.
user www-data는 Nginx 워커 프로세스가 어떤 시스템 사용자 권한으로 실행될지 지정합니다. www-data는 Ubuntu에서 웹 서버용으로 기본 생성되는 사용자입니다. 보안상 root로 실행하면 안 되기 때문에 권한이 낮은 사용자를 지정하는 겁니다.
worker_processes auto는 워커 프로세스 수를 설정합니다. auto로 두면 서버의 CPU 코어 수에 맞춰서 자동으로 설정됩니다. 코어가 4개면 워커 프로세스도 4개가 뜹니다. 이전 글에서 Nginx가 적은 수의 프로세스로 많은 요청을 처리한다고 했는데, 여기서 그 프로세스 수가 결정됩니다.
pid /run/nginx.pid는 Nginx 마스터 프로세스의 PID를 저장할 파일 경로입니다. 시스템이 Nginx를 관리할 때 이 파일을 참조합니다. 건드릴 일이 거의 없습니다.
events 블록
events 블록은 Nginx의 연결 처리 방식을 설정하는 곳입니다.
events {
worker_connections 1024;
}
worker_connections 1024는 각 워커 프로세스가 동시에 처리할 수 있는 최대 연결 수입니다. 워커 프로세스가 4개이고 worker_connections가 1024면 이론상 동시 연결 4096개까지 처리할 수 있다는 뜻입니다. 트래픽이 많은 서비스라면 이 숫자를 늘려야 할 수도 있지만, 일반적인 사이트에서는 기본값으로 충분합니다.
이 블록에 multi_accept on을 추가하면 워커 프로세스가 한 번에 여러 연결을 받아들일 수 있습니다. 기본값은 off인데, 트래픽이 많다면 켜는 게 좋습니다.
http 블록
http 블록이 가장 큰 블록이고, 웹 서버로서의 핵심 설정이 여기에 들어갑니다.
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
include /etc/nginx/mime.types는 아까 말한 MIME 타입 매핑 파일을 불러오는 겁니다. include는 다른 파일의 내용을 그 자리에 삽입하는 지시어입니다.
default_type application/octet-stream은 MIME 타입을 판별할 수 없는 파일의 기본 타입입니다. octet-stream으로 설정하면 브라우저가 해당 파일을 다운로드하게 됩니다.
sendfile on은 파일 전송 시 커널에서 직접 처리하게 하는 옵션입니다. 유저 공간을 거치지 않고 커널 레벨에서 파일을 보내기 때문에 정적 파일 전송 성능이 좋아집니다.
keepalive_timeout 65는 클라이언트와의 연결을 유지하는 시간입니다. 초 단위이고, 이 시간 동안 추가 요청이 없으면 연결을 닫습니다.
맨 아래에 있는 두 줄의 include가 중요합니다. conf.d 폴더의 .conf 파일과 sites-enabled 폴더의 파일을 전부 불러옵니다. 즉 사이트별 설정 파일은 이 include를 통해 http 블록 안에 포함되는 구조입니다.
server 블록 — 사이트별 설정
server 블록은 http 블록 안에 들어가고, 각 사이트(또는 가상 호스트)의 설정을 담당합니다. 보통 sites-available 폴더에 별도 파일로 만듭니다.
server {
listen 80;
server_name today-play.com www.today-play.com;
root /var/www/today-play;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
listen 80은 이 서버 블록이 80번 포트에서 요청을 받겠다는 뜻입니다. HTTPS를 적용했다면 listen 443 ssl도 추가됩니다.
server_name은 이 서버 블록이 어떤 도메인의 요청을 처리할지 지정합니다. 하나의 서버에 여러 도메인을 연결할 수 있는데, server_name이 다른 server 블록을 여러 개 만들면 됩니다. Nginx가 요청이 들어올 때 Host 헤더를 보고 어떤 server 블록으로 보낼지 결정합니다.
root는 웹 사이트의 루트 디렉토리입니다. 사용자가 today-play.com/about.html을 요청하면 /var/www/today-play/about.html 파일을 찾아서 보내줍니다.
index는 디렉토리에 접근했을 때 기본으로 보여줄 파일입니다. today-play.com으로 접속하면 /var/www/today-play/index.html을 보여줍니다.
location 블록 — URL 경로별 처리
location 블록은 server 블록 안에 들어가고, 특정 URL 경로에 대한 처리 방식을 정의합니다.
location / {
try_files $uri $uri/ =404;
}
이건 모든 경로에 대해 파일이 있으면 보여주고, 디렉토리면 디렉토리 안의 index 파일을 보여주고, 둘 다 아니면 404 에러를 반환하라는 뜻입니다.
location 블록은 여러 개 만들 수 있고 경로별로 다른 동작을 지정할 수 있습니다.
location /images/ {
alias /var/www/static/images/;
}
location /api/ {
proxy_pass http://localhost:3000;
}
첫 번째는 /images/ 경로로 들어오는 요청을 /var/www/static/images/ 디렉토리에서 찾으라는 설정입니다. 두 번째는 /api/로 시작하는 요청을 로컬의 3000번 포트에서 돌아가는 애플리케이션 서버로 넘기라는 설정입니다. 이게 리버스 프록시 설정입니다. Node.js나 Django 같은 백엔드 서버를 Nginx 뒤에 두고 싶을 때 이렇게 합니다.
location 블록의 매칭 방식도 알아두면 좋습니다. 기본적으로 앞에서부터 일치하는 경로를 찾는데, 정확히 일치하는 경로를 지정하고 싶으면 등호를 사용합니다.
location = /favicon.ico {
log_not_found off;
access_log off;
}
이건 정확히 /favicon.ico 요청에만 적용되고, 해당 파일이 없어도 로그를 남기지 않겠다는 설정입니다. 파비콘이 없을 때 로그가 계속 쌓이는 걸 방지할 수 있습니다.
전체 구조를 한눈에 보면
Nginx 설정 파일은 블록이 중첩되는 구조입니다. 정리하면 이렇습니다.
nginx.conf 파일 안에 최상위 지시어들이 있고, 그 안에 events 블록이 있고, http 블록이 있습니다. http 블록 안에 server 블록이 들어가고, server 블록 안에 location 블록이 들어갑니다. 바깥쪽 블록에서 설정한 값은 안쪽 블록으로 상속됩니다. 안쪽에서 같은 지시어를 다시 설정하면 덮어씌워집니다.
nginx.conf
├── 최상위 (user, worker_processes, pid)
├── events { ... }
└── http { ... }
├── 공통 설정 (mime.types, sendfile, keepalive)
├── include conf.d/*.conf
└── include sites-enabled/*
└── server { ... }
├── listen, server_name, root
└── location / { ... }
└── location /api/ { ... }
실무에서 nginx.conf 자체를 직접 많이 수정하는 경우는 드뭅니다. 대부분 sites-available에 사이트별 설정 파일을 만들고, sites-enabled에 링크를 걸어서 관리합니다. nginx.conf에는 전체 서버에 공통으로 적용되는 설정만 두는 게 깔끔합니다.
설정 파일 수정 후 확인하는 방법
설정 파일을 수정했으면 바로 리로드하기 전에 문법 오류가 없는지 확인하는 게 좋습니다.
sudo nginx -t
이 명령어를 실행하면 설정 파일 문법을 검사합니다. “syntax is ok”와 “test is successful”이 나오면 문제가 없는 겁니다. 에러가 있으면 어느 파일 몇 번째 줄에서 문제가 생겼는지 알려줍니다.
문법 확인이 끝났으면 설정을 반영합니다.
sudo nginx -s reload
reload는 실행 중인 Nginx를 중단하지 않고 설정만 다시 읽어들입니다. 사이트가 운영 중이어도 안전하게 적용할 수 있습니다. restart와 다른 점은, reload는 기존 연결을 끊지 않고 새 설정을 적용한다는 겁니다.
설정할 때 자주 실수하는 것들
가장 흔한 실수는 세미콜론을 빠뜨리는 겁니다. Nginx 설정에서 각 지시어는 반드시 세미콜론으로 끝나야 합니다. 빠뜨리면 nginx -t에서 바로 에러가 나는데, 에러 메시지가 가리키는 줄이 실제 실수한 줄과 다를 수 있어서 헷갈릴 수 있습니다.
두 번째는 sites-available에 파일만 만들고 sites-enabled에 링크를 안 거는 경우입니다. 심볼릭 링크를 만드는 명령어는 이렇습니다.
sudo ln -s /etc/nginx/sites-available/today-play.com /etc/nginx/sites-enabled/
세 번째는 default 설정 파일과 충돌하는 경우입니다. sites-enabled에 default 파일이 남아있으면 내 사이트 설정과 충돌할 수 있습니다. 내 사이트 설정이 제대로 안 먹힌다면 default 링크를 삭제하고 다시 reload해보면 해결되는 경우가 많습니다.
마무리
Nginx 설정 파일은 블록 구조만 이해하면 절반은 끝난 겁니다. nginx.conf가 전체 뼈대를 잡고, server 블록이 사이트를 정의하고, location 블록이 경로별 동작을 처리합니다. 처음에는 설정 파일이 낯설지만 실제로 건드리는 부분은 server와 location 블록이 대부분이라 몇 번 해보면 금방 익숙해집니다. 다음 글에서는 리눅스 서버에서 자주 다루게 되는 파일 권한 설정에 대해 다뤄보겠습니다.
Leave a Reply