- inflearn: https://www.inflearn.com/course/비전공자도-이해-nginx-입문-실전/dashboard
- 수업 자료: https://jscode.notion.site/16011062ff0780aa87a3e879cb3ef482
Preview
내가 Nginx 를 처음으로 접한 경험은 Docker Private Image Registry 를 구성하는 과정에서 HTTPS 인증서 적용을 위해 Nginx를 잠깐 경험해봤다.
실무에서는 주로 아파치(Apache) 를 웹서버로 사용해서 사용할 기회가 없었는데 예제를 통해 잠깐 경험해보니 충분히 공부할 가치가 높다고 생각했다. 백엔드 개발자 입장에서 웹서버 + 리버스 프록시 + 로드밸런서 기능까지 3 in 1 으로 쓸 수 있으니 충분히 가치가 있다고 느꼈다.
해당 인프런 강의를 수강하기 이전에 비전공자도 이해할 수 있는 DB 설계 입문/실전 을 수강한 경험이 있는데 쉽게 풀어서 설명해주는 강사님이 인상 깊어서 강사님의 강의로 선택하게 되었다.
앞선 경험을 통해 이미 Nginx 에 대해 간략하게 알고 있지만 약 3시간 정도 부담되지 않는 시간으로 Nginx의 기능에 대해 경험해보고자 한다.
Introduce
주석 공부법
- 코드 한 줄마다 어떤 의미를 가지고 있는지 주석을 달면서 학습하는 방법.
- 시간이 오래걸려 비효율적일 것 같지만 한 줄씩 주석을 달다보면 어느순간부터 코드를 대부분 이해하게 된다.
Nginx 개본 개념
Nginx는 왜 사용해야 할까 ?
현업에서 Nginx를 안 쓰고 있는 기업을 찾기가 어렵다. 현업에서 많이 쓰고 있다는 것은 (백엔드)개발자로 취업을 하기 위해 필수로 알아야 하는 기술임을 뜻한다.
Nginx 는 아래와 같이 다양한 기능을 가지고 있는 S/W 이다. 아래 기능들은 서버스를 운영할 때 필수적으로 사용하게 되는 기능들이다.
- 정적 컨텐츠 제공
- SSL 처리
- 로드 밸런싱
- 장애 대응
- 캐싱
- 보안 처리 (IP 차단, 요청 수 제한)
Nginx를 배운다는 것은 Nginx의 설정 파일을 내가 구성하고 싶은 대로 응용할 수 있게끔 배워야 한다. 그러려면 자주 쓰이는 Nginx의 문법과 기본적인 파일 구조를 익혀야 한다.
Apache VS Nginx
최근 Nginx 가 Apache 점유율을 뛰어 넘었다. Nginx를 많이 사용하는 가장 큰 이유는 Apache에 비해 훨씬 많은 트래픽을 처리할 수 있는 구조를 가지고 있다. (Nginx가 성능이 더 좋다.)
Nginx 설치 및 실행
⚠️ 필자는 앞서 Docker Container 을 통해 Nginx를 구성하였으나, 본 강의에는 AWS EC2 인스턴스에서 구성하여 진행하였다. 따라서 본 글에서도 동일하게 EC2 인스턴스 환경에서 실습을 진행한다.
Ubuntu 환경에서 Nginx 설치하기
# apt에서 설치 가능한 패키지 리스트(최신 패키지, 버전 등)를 최신화시킨다.
# apt는 리눅스에서 사용되는 소프트웨어 패키지를 설치 및 관리할 수 있게 도와주는 툴이다.
# npm 또는 gradle과 같은 패키지 관리 도구와 비슷하다고 생각하면 된다.
$ sudo apt update
# nginx 설치에 필요한 라이브러리 설치
$ sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring
# nginx 공식 패키지를 안전하게 설치하기 위한 보안 조치이다. 자세한 코드 의미는 몰라도 된다.
# 다만, curl, gpg, tee, |, >, /dev/null, echo가 무슨 기능을 하는 명령어인지는 정리해두자.
$ curl <https://nginx.org/keys/nginx_signing.key> | gpg --dearmor \\
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
$ gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg
$ 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
# nginx 설치
$ sudo apt update
$ sudo apt install nginx
Nginx 실행하기
# nginx 상태 확인
$ sudo systemctl status nginx
# nginx 시작
$ sudo systemctl start nginx
# nginx 상태 확인
$ sudo systemctl status nginx
- 실행 확인을 위하여 http://{EC2 IP 주소} 로 접속하여 본다.
Nginx 로그 확인하기
- 로그 파일 위치 : /var/log/nginx
- access.log : Nginx 서버로 접근한 요청에 대한 정보
- error.log : 에러 메세지에 대한 내용
Nginx를 활용해 웹 사이트 배포하기
- 웹 서버(Web Server)는 사용자의 요청이 들어올 때마다 HTML, CSS, JS, 이미지와 같은 파일들을 제공하는 컴퓨터를 의미한다.
- Nginx 는 사용자의 요청이 들어올 때마다 파일(HTML, CSS, JS, 이미지 등)을 제공할 수 있는 기능을 가지고 있다.
- Nginx를 활용해 웹 사이트를 배포할 수 있다. 이걸 보고 ‘Nginx’가 웹 서버(Web Server) 역할을 한다’라고 한다.
Nginx 기본 문법 해석
- Nginx 설정 파일 위치 : /etc/nginx/nginx.conf
- Nginx 에서 가장 근본이 되는 설정 파일 (루트 설정 파일)
- 전역적으로 설정되어야 하는 내용(워커 프로세스 개수, 로그 저장 위치 등)
- 기본 웹 서버(Web Server) 설정 파일 : /etc/nginx/conf.d/default.conf
# server : '하나의 웹 사이트에 관련된 설정'을 관리하는 단위 ('server 블럭'이라고 부름)
server {
# localhost:80으로 들어오는 요청을 이 server 블럭에서 처리하도록 설정
# (server_name이 일치하는 server 블럭이 없는 경우 첫 번째 정의되어 있는 server 블럭을 기반으로 처리)
# (아직은 정확히 몰라도 된다. 나중에 '멀티 도메인' 기능을 배우면 쉽게 이해할 수 있다.)
listen 80;
server_name localhost;
# / 으로 시작하는 모든 경로를 처리 (ex. /index.html)
location / {
# /jscode.html로 요청이 들어오면 /usr/share/nginx/html/jscode.html 파일로 응답
root /usr/share/nginx/html;
# /로 요청이 들어오면 /usr/share/nginx/html/index.html로 응답
# 만약 /usr/share/nginx/html/index.html이 없을 경우, /usr/share/nginx/html/index.htm으로 응답
index index.html index.htm;
}
# Nginx에서 500, 502, 503, 504의 상태 코드가 발생했을 때 /50x.html로 redirect
error_page 500 502 503 504 /50x.html;
# /50x.html과 완전히 일치하는 경로를 처리
location = /50x.html {
# /50x.html로 요청이 들어오면 /usr/share/nginx/html/50x.html 파일로 응답
root /usr/share/nginx/html;
}
}
Nginx 디버깅 절차
# step 1. nginx 실행을 확인하라
$ sudo systemctl status nginx
# step 2. 문법을 점검하라
$ sudo nginx -t
# step 3. 로그를 확인하라
$ tail -f /var/log/nginx/access.log
$ tail -f /var/log/nginx/error.log
# step 4. 문제 해결 후 설정파일을 반영한다.
$ sudo nginx -s reload
.
[실습 생략]
.
한 서버에서 다른 도메인을 가진 여러 웹 사이트 배포하기 (멀티도메인)
/etc/nginx/conf.d/default.conf 에 두 개의 서버를 등록하여 멀티 도메인을 적용한다.
server {
listen 80;
server_name react.manutd.co.kr;
location / {
root /usr/share/nginx/nginx-frontend-react/dist;
index index.html;
}
}
server {
listen 80;
server_name next.manutd.co.kr;
location / {
root /usr/share/nginx/nginx-frontend-next/out;
index index.html;
}
}
Nginx를 활용한 HTTPS 적용시키기
HTTPS 를 적용해야 하는 이유
- 보안적인 이유 (HTTPS는 암호화 통신 프로토콜)
- 신뢰성 문제 (브라우저 단에서 경고 메세지 발생)
Nginx, Certbot을 활용해 HTTPS 적용하기
Certbot 이란 ? 웹 사이트에서 Let 's Encrypt 인증서 를 발급받고 갱신 및 관리하며 자동으로 사용하는 무료 오픈 소스 소프트웨어 도구
# certbot 설치
$ sudo snap install --classic certbot
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
# **HTTPS 인증서 발급받기
# 반드시 도메인을 먼저 연결(레코드 등록)한 뒤에 위 명령어를 쳐야 정상 작동한다.**
# 자동으로 default.conf 파일을 수정하여 반영한다.
$ sudo certbot --nginx -d <도메인 주소>
설정 파일 분리해서 관리하기 (include)
- default.conf 파일에서 다음과 같이 include 해서 파일을 분리할 수 있다.
# default.conf
include conf.d/web/react.manutd.conf;
include conf.d/web/next.manutd.conf;
.
.
또는
.
.
include conf.d/web/*.conf;
리버스 프록시(Reverse Proxy)를 활용해 백엔드 서버 배포하기
용어
- 프록시(Proxy) : 중계(중간에서 연결해주는 것)의 의미
- 프록시 서버(Proxy Server) : 중간 역할을 해주는 서버
- 포워드 프록시(Foward Proxy) 서버 : 보내려고 하는 요청을 관리 또는 보안 처리를 위한 용도 (ex. 사내 방화벽)
- 리버스 프록시(Reverse Proxy) : 들어오는 요청을 관리 또는 보안 처리 하기 위한 용도 (ex. HTTPS 처리, 요청 수 제한, 로드 밸런싱)
리버스 프록시는 들어오는 요청을 관리 또는 보안 처리를 하기 위해 사용한다. (악의적인 행위가 들어오는 것이 예상될 경우 활용한다)
Spring Boot 서버 배포하기
- 준비사항 : JDK 17 설치
$ sudo apt update && /
sudo apt install openjdk-17-jdk -y
# 설치 확인
$ java -version
- spring 빌드 및 실행
$ ./gradlew clean build -x test
$ cd build/libs
$ nohup java -jar nginx-backend-springboot-0.0.1-SNAPSHOT.jar &
# 8080번 포트에서 실행되고 있는 프로세스 조회
$ lsof -i:8080
- conf 파일 작성
server {
listen 80;
server_name api.manutd.co.kr;
# / 으로 시작하는 모든 경로를 처리
location / {
# 들어온 요청을 전부 <http://localhost:8080>(Spring Boot 서버)로 전달
proxy_pass <http://localhost:8080>;
}
}
- HTTPS 적용(DNS A 레코드에 사전 등록되어 있어야 한다.)
$ sudo certbot --nginx -d [api.manutd.co.kr](<http://api.manutd.co.kr>)
IP당 요청 수 제한하기
- api.conf 파일 수정
# limit_req_zone : 요청 수를 제한하기 위한 메모리 공간(zone)과 요청 속도(rate)를 정의
# $binary_remote_addr : 요청 수를 제한하는 기준을 클라이언트의 IP로 설정
# zone=mylimit:10m : 메모리 공간(zone)의 이름을 mylimit이라고 지정,
메모리 공간의 크기를 10MB 제한 (약 16만개의 IP 주소를 관리할 수 있음)
# rate=3r/s : 1초에 최대 3개의 요청만 허용
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=3r/s;
server {
# limit_req_zone에서 정의한 mylimit이라는 조건을 이 server 블럭에 적용
**limit_req zone=mylimit;**
# 요청이 제한됐을 때 429(Too Many Requests) 상태 코드를 반환
**limit_req_status 429;**
server_name api.manutd.co.kr;
location / {
proxy_pass <http://localhost:8080>;
}
.
.
.
(생략)
.
# 설정 파일 재로드
$ sudo nginx -s reload
Nginx를 로드 밸런서(Load Balancer)로 사용하기
로드 밸런서 : 사용자의 요청을 여러 대의 서버로 골고루 전달하기 위한 장치 (트래픽 부하 분산)
- 8081 포트를 사용하는 spring boot server 추가
$ cd ~/nginx-backend-springboot/build/libs
$ nohup java -jar nginx-backend-springboot-0.0.1-SNAPSHOT.jar --server.port=8081 &
$ lsof -i:8081
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=3r/s;
# 로드 밸런싱 대상 서버들을 upstream이라는 그룹으로 묶음
# upstream 그룹의 이름은 backend라고 지정
**upstream backend {
server localhost:8080;
server localhost:8081;
}**
server {
# limit_req_zone에서 정의한 mylimit이라는 조건을 이 server 블럭에 적용
**limit_req zone=mylimit;**
# 요청이 제한됐을 때 429(Too Many Requests) 상태 코드를 반환
**limit_req_status 429;**
server_name api.manutd.co.kr;
# upstream 그룹에서 지정한 서버들로 요청이 분산됨
location / {
proxy_pass **<http://backend>;**
}
.
.
.
(생략)
.
# 설정 파일 재로드
$ sudo nginx -s reload
Review
짧은 시간동안 Nginx 를 익히기에 아주 좋은 강의였다. 다만 해당 강의의 특징은 강의명에서도 알 수 있듯이 비전공자도 이해할 수 있는 수준에서 강의를 진행한다는 것이다. 그 말은 즉, 전공자 또는 실무자 입장에서는 다소 강의 내용이 쉬울 수 있다는 것이다. 만약 본인이 비전공자 입장에서 새롭게 배우는 위치라면 해당 강사님의 강의를 적극 추천하지만 전공자 또는 실무라자면 예제 문서를 보고 잠깐 따라해보는 것이 좀 더 효율적이라고 느꼈다.
'Study > Back-End' 카테고리의 다른 글
[Inflearn] 비전공자도 이해할 수 있는 DB 설계 입문/실전 (1) | 2025.05.04 |
---|