
Nginx 시리즈는 21년도 12월에 사이드 프로젝트를 위해 정리했던 내용을 토대로 작성한 글이다.
요즘에는 AWS 프리티어 덕분에 Nginx를 직접 설치해서 사용하는 경우는 드물어 보인다.
나 또한 사이드 프로젝트 이후 지난 2년간 현업에서도 개인적으로도 Nginx를 설치하여 사용한 적은 없었다.
그렇다면 'Nginx 지식은 현재 중요하지 않을까?' 적어도 내겐 아니었다.
현업에 들어가기 전, AWS 사용해 보기 전 Nginx를 사용해 본 경험은 내게 큰 시야를 가져다주었기 때문이다.
그리고 지금부터 내가 얻은 큰 시야에 대해 얘기해 보려 한다.
웹 서비스를 제공하기 위한 인프라는 복잡하며, 회사에 따라 서비스에 따라 조금씩 다른 구조를 가진다.
하지만 아무리 다르다고 하더라도 큰 골격은 비슷하다.
1. 서비스 도메인을 관리하는 DNS
2. 정적인 자원을 호스팅하는 '웹서버'
3. API 같은 동적인 자원을 호스팅하는 'API 서버' (또는 'WAS')
4. 데이터를 저장하고 조회하기 위한 'DBMS'
물론 작은 서비스나 초기 서비스의 경우 '웹서버'와 'API 서버'를 분리하지 않는 구조를 사용할 수 있다.
이 경우를 제외한 웹서비스는 정적인 자원을 호스팅하는 서버와 동적인 자원을 호스팅 하는 서버로 나뉜다.
Nginx는 이러한 인프라를 직관적이고 손쉽게 구성할 수 있도록 해준다.
먼저 Nginx는 AWS를 비교하는 것 자체가 오류라고 느껴질지 모른다.
그럼에도 복잡한 AWS 기능을 단순화하여 Nginx와 비교한다면 AWS가 한결 쉽게 느껴질 수 있다고 생각한다.
기본 인프라 요구 사항
1. https를 지원하는 도메인
2. 클라이언트 사이드 코드인 'React'와 각종 정적인 지원을 호스팅 하는 웹서버
3. N개의 API서버
4. 부하 분산을 위한 로드벨런서(L7)
5. 데이터를 저장하고 조회할 DB

(당연하게도) Nginx로 불가능한 인프라
설정 파일에 따라 Nginx 이러한 역할을 수행한다.
upstream api-server 에 정의된 API 서버로 트래픽 전달upstream 은 L7 로드밸런서 역할을 수행할 수 있다.user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# 1. 포워드할 upstream 프록시 서버 설정 - api 서버
upstream api-server {
server api-1:8080; # api-1: ip 주소 or 도커 서비스 이름
server api-2:8080;
}
# 2. 가상 호스트 서버 - 1) http => https 리다이렉팅
server {
listen 80;
server_name domain.com;
server_tokens off;
location / {
return 301 https://$host$request_uri;
}
}
# 2. 가상 호스트 서버 - 2) openssl을 적용한 https 서버
server {
listen 443 ssl;
listen [::]:443;
server_name domain.com;
server_tokens off;
## ssl 설정 - openssl 전용 ##
ssl_certificate /etc/nginx/ssl/lesstif.com.crt;
ssl_certificate_key /etc/nginx/ssl/lesstif.com.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# 3. 기본 루트 설정
location / {
root /usr/share/nginx/html/; # 호스팅할 build 파일 경로
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
}
# 4. upstream 그룹을 호출하여 트래픽 전달
location /api {
proxy_pass http://api-server; # api-server: upstream 이름
proxy_redirect off;
proxy_set_header Host $host;
# ...Frowarded 헤더 설정 생략
proxy_cache_bypass $http_upgrade;
proxy_http_version 1.1;
}
}
}

구성 설명
Route53: AWS에서 제공하는 DNS 시스템이다.CloudFront: CDN 이라 불리며 정적인 콘텐츠를 빠르게 제공하기 위한 구성이다.S3: AWS에서 제공하는 정적 파일을 호스팅 하는 서버이다. ALB
[Nginx]
[AWS]
여기서 DNS 시스템을 설명하기에는 무리가 있기 때문에 맥락만 설명한다.
어떤 도메인이든 DNS 서버를 ip 주소가 클라이언트로 응답된다.
DNS는 한개가 아니며 계층적 조회된다.
AWS의 경우 자신들의 DNS 서비스를 Route53으로 칭할 뿐 결국 DNS 서비스이다.
[Nginx]
[AWS]
Nginx와 AWS 가장 다른 구성은 '정적 자원은 CloudFront'를 '동적 자원은 ALB'를 사용하는 구성이다.
CloudFront는 기본적으로 정적인 콘텐츠를 다양한 엣지 서버에서 빠르게 응답하는 서비스이다.
때문에 CloudFront는 EC2와 직접적인 통신은 지원하지 않는다.
[Nginx]
upstream 블록을 통해 API 서버들을 그룹화 한다. upstream 으로 그룹화된 API로 요청을 전달한다.[AWS]
위의 두 아키텍처 모두 22년 23년에 각각 사이드 프로젝트에서 사용한 구조이다.
실제 현업에서는 서버리스'나 컨테이너 환경 기반의 'ECS', 'ECK' 등등의 기술이 추가된다.
게다가 안전성(내결함성 고가용성)과 보안상의 이유로 더욱 복잡한 구조를 가진다.
신입 그리고 주니어에게 AWS는 꽤나 무섭게 느껴진다. 적어도 나는 그랬다.
AWS 자체가 너무 거대한 산처럼 느껴지고 과금이 무서웠기 때문에 22년 초 사이드 프로젝트에서는 온프레미스 환경에서 프로젝트를 진행하였다. (iptime의 ddns 설정, 우분투 설치 등 삽질의 여정이었다.)
그 후 주니어로 회사를 다니며 AWS와 친해졌다. 이때 내가 했던 Nginx와 사투의 경험이 도움이 되었다.
결과적으로 23년 현재 팀 사이드 프로젝트에서 메인으로 인프라를 구성하여 운영할 수 있을 정도로 성장하였다.
때문에 내 삽질의 기록이 누군가에게 도움이 되기를 바라며 이번 시리즈를 정리한다.