Study/Back-End

[Inflearn] 비전공자도 이해할 수 있는 Nginx 입문/실전

Developer_Jay 2025. 5. 6. 16:00
728x90

 

 

 

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 를 익히기에 아주 좋은 강의였다. 다만 해당 강의의 특징은 강의명에서도 알 수 있듯이 비전공자도 이해할 수 있는 수준에서 강의를 진행한다는 것이다. 그 말은 즉, 전공자 또는 실무자 입장에서는 다소 강의 내용이 쉬울 수 있다는 것이다. 만약 본인이 비전공자 입장에서 새롭게 배우는 위치라면 해당 강사님의 강의를 적극 추천하지만 전공자 또는 실무라자면 예제 문서를 보고 잠깐 따라해보는 것이 좀 더 효율적이라고 느꼈다.

728x90