
최근 프로젝트에서 Nginx를 통해 포트 제한 문제를 해결하고 HTTPS 환경을 구축했습니다. 설치했다에서 끝나는 것이 아닌 '왜 Nginx가 현대 인프라의 표준이 되었는지' 공식 문서와 실무 관점에서 정리했습니다.
전통적인 웹 서버인 Apache가 요청당 하나의 프로세스/스레드를 사용하는 Process-driven 방식이라면 Nginx는 Event-driven(비동기 이벤트 루프) 구조를 채택하고 있습니다.
| 비교 항목 | Process-driven (Apache 방식) | Event-driven (Nginx 방식) |
|---|---|---|
| 핵심 비유 | 손님마다 전담 웨이터가 1명씩 붙음 | 웨이터 1명이 여러 테이블을 돌며 주문만 받음 |
| 자원 사용 | 요청 수에 비례하여 급증 | 요청이 많아도 낮고 일정하게 유지 |
| 동시 접속 | 수천 명 이상 시 서버 부하 급증 | 수만 명 이상의 동시 접속도 거뜬히 처리 |
| 주요 용도 | 복잡한 비즈니스 로직 처리 | 대규모 트래픽 처리, 리버스 프록시 |
Context Switching이란, CPU가 한 프로세스(또는 스레드)에서 다른 프로세스로 실행을 넘길 때 현재까지의 작업 상태(Context)를 저장하고 다음 작업의 상태를 불러오는 과정
Context(문맥/상태): 프로그램이 어디까지 실행되었는지(프로그램 카운터), 어떤 값을 계산 중이었는지(레지스터 상태) 등의 정보
교환 과정: A 작업을 멈추고 현재 상태를 메모리에 기록 → B 작업의 이전 상태를 메모리에서 불러옴 → B 작업 실행.
클라이언트와 백엔드 서버(Docker 컨테이너) 사이의 중개자입니다.
여러 대의 서버에 트래픽을 분산합니다.
이미지, HTML, JS 파일 같은 정적 자원을 어플리케이션(Spring/Node.js) 단까지 보내지 않고 Nginx가 메모리 캐시를 활용해 즉시 응답합니다. 이는 전체 시스템의 응답 속도를 비약적으로 향상시킵니다.
HTTPS 암호화 해제 작업을 Nginx가 전담합니다. 백엔드 서버는 복잡한 암호화 계산을 할 필요 없이 비즈니스 로직에만 집중할 수 있게 됩니다.
Nginx 설정 (/etc/nginx/sites-available/default)은 context 구조로 이루어져 있습니다. 이번 프로젝트에서 사용한 location 블록의 의미는 다음과 같습니다.
server {
listen 80;
server_name [도메인IP];
# 프론트엔드: "/" 경로로 들어오면 nnnn번 컨테이너로!
location / {
proxy_pass http://127.0.0.1:nnnn;
proxy_set_header Host $host; # 원본 호스트 정보 유지
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 실제 클라이언트 IP 전달
}
# 백엔드: "/api/" 경로로 시작하면 xxxx번 컨테이너로!
location /api/ {
proxy_pass http://127.0.0.1:xxxx;
}
}
docker ps로 상태를 확인합니다.www-data 계정으로 실행됩니다. 정적 파일을 서빙할 때 해당 폴더에 접근 권한이 있는지 확인해야 합니다.