과정을 즐기자

EC2에 Nginx 구성하여 도메인, Https 적용하기 본문

DevOps

EC2에 Nginx 구성하여 도메인, Https 적용하기

320Hwany 2023. 5. 29. 17:11

원하는 분야의 CS 면접 질문을 이메일로 전송해주는 서비스를 만들고 있었습니다.
React 기반의 프론트, Spring 기반의 백엔드를 배포할 때 구매한 도메인을 적용하고

Https도 적용 해보겠습니다. 같은 EC2 서버에서 프론트, 백엔드 모두 배포를 진행하였습니다.

EC2 인스턴스는 이미 만들었다는 가정을 하고 진행하겠습니다.

 

도메인 구매 후 EC2와 연결하기

저는 가비아에서 도메인을 구매하였습니다.

구매 후 DNS 관리에서 레코드 수정에 들어가 EC2 인스턴스의 ip 주소를 입력합니다. 

값/위치 부분에 ip 주소를 적으면 됩니다.

Backend 배포하기

 

github에 올라와 있는 프로젝트를 clone해서 가져왔습니다. 

폴더 구조는 sendQuiz 아래 frontend, backend가 있습니다.

먼저 backend 아래에는 src, build, gradlew .. 등이 있습니다.

이때 git clone으로 가져온 프로젝트는 secret key와 같이 반드시 숨겨야 하는 정보를 가져올 수 없기 때문에

EC2 서버의 backend 폴더 안에 직접 application-prod.yml, application-dev.yml을 생성하였습니다.

이제 deploy.sh 스크립트를 만들어 스크립트를 실행하면 git pull을 시작으로 테스트 및 빌드를 하도록 하겠습니다.  

 

deploy.sh

#!/bin/bash

REPOSITORY=/home/ubuntu
PROJECT_NAME=sendQuiz

cd $REPOSITORY/$PROJECT_NAME/

echo "> Git pull"

git pull

echo "> 프로젝트 build 시작"

cd backend

export SPRING_PROFILES_ACTIVE=dev
./gradlew test
echo "> 테스트 수행 완료"

export SPRING_PROFILES_ACTIVE=prod
./gradlew build -x test
echo "> Build 완료"

echo "> Build 파일 복사"

cd $REPOSITORY
cp $REPOSITORY/$PROJECT_NAME/backend/build/libs/*.jar $REPOSITORY/

echo "> 현재 구동 중인 애플리케이션 pid 확인"

CURRENT_PID=$(pgrep -f *SNAPSHOT.jar)

echo "현재 구동 중인 애플리케이션 pid: $CURRENT_PID"

if [ -z "$CURRENT_PID" ]; then
    echo "> 현재 구동 중인 애플리케이션이 없으므로 종료하지 않습니다."
else
    echo "> kill -15 $CURRENT_PID"
    kill -15 $CURRENT_PID
    sleep 5
fi

echo "> 새 애플리케이션 배포"

JAR_NAME=$(find $REPOSITORY -name "*SNAPSHOT.jar" -type f | sort -n | tail -1)

echo "> JAR Name: $JAR_NAME"

cd $REPOSITORY/$PROJECT_NAME/backend
export SPRING_PROFILES_ACTIVE=prod
nohup java -jar -Duser.timezone=Asia/Seoul $JAR_NAME 2>&1 &

이제 ./deploy.sh 명령어로 백엔드 애플리케이션을 배포할 수 있습니다.  

 

Frontend 배포하기

frontend 폴더에 들어가서  npm run build 명령어로 build 폴더를 생성합니다.  

이렇게 만든 build를 Nginx를 사용하여 배포를 합니다.   

 

Nginx 설치

sudo apt-get install nginx -y

Nginx 설치 후 /etc/nginx/sites-enabled에 있는 default.conf를 만들어 다음 명령어를 작성합니다.  

 

default.conf

server {
  server_name send-quiz.store www.send-quiz.store;

  location / {
    root /home/ubuntu/sendQuiz/frontend/build;
    index index.html index.htm;
    try_files $uri $uri/ /index.html;
    error_page 405 = $uri;
  }

  location /api {
    proxy_pass http://{ip 주소}:8080;
  }
}

기본적으로 location을 build로 설정하였고 /api 로 시작하는 url의 경우에는 백엔드 요청이므로

{ip 주소} : 8080으로 요청을 보내도록 설정하였습니다.    

 

이렇게 설정하면 send-quiz.store 도메인을 입력하면 기본적으로 react로 빌드한 파일을 보여주며
만약 send-quiz.store/api/ 로 시작하는 요청이 온다면 아까 배포한 8080 포트로 요청이 갑니다.

 

HTTPS 적용하기

# certbot을 snap 명령어로 설치, 실행하기 때문에 snap을 먼저 설치한다
sudo snap install core
sudo snap refresh core

# 기존에 설치된 certbot을 제거한다
# 공식 가이드에선 certbot명령어를 사용할 때 snap이 사용되게 하기 위함이라고 설명한다
sudo apt-get remove certbot

# certbot을 설치한다
sudo snap install --classic certbot

# certbot 명령어가 실행될 수 있게 세팅한다
sudo ln -s /snap/bin/certbot /usr/bin/certbot

# nginx가 아닌 apache를 웹서버로 사용할 경우, sudo certbot --apache 가 된다
sudo certbot --nginx -d send-quiz.store

# 놀랍게도 certbot은 CLI몇 줄로 SSL을 적용해줄 뿐 아니라 자동 리뉴얼까지 해준다;
# 처음 설치할 때부터 이러한 cron job 처리를 위한 내용이 함께 들어온다
# 아래 명령어로 자동 리뉴얼이 적용되고 있는지 확인할 수 있다
sudo certbot renew --dry-run

 

이제 최종적으로 만들어진 /etc/nginx/sites-enabled/default.conf 를 확인해보겠습니다.  

default.conf

server {
  server_name send-quiz.store www.send-quiz.store;

  location / {
    root /home/ubuntu/sendQuiz/frontend/build;
    index index.html index.htm;
    try_files $uri $uri/ /index.html;
    error_page 405 = $uri;
  }

  location /api {
    proxy_pass http://3.34.119.43:8080;
  }

   underscores_in_headers on;

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/send-quiz.store/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/send-quiz.store/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = send-quiz.store) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


  listen 80;
  server_name send-quiz.store www.send-quiz.store;
    return 404; # managed by Certbot

}

 

https 가 적용된 것을 확인할 수 있습니다!

 

참고한 자료

 

스프링 부트와 AWS로 혼자 구현하는 웹 서비스 | 이동욱 - 교보문고

스프링 부트와 AWS로 혼자 구현하는 웹 서비스 | 가장 빠르고 쉽게 웹 서비스의 모든 과정을 경험한다. 경험이 실력이 되는 순간!이 책은 제목 그대로 스프링 부트와 AWS로 웹 서비스를 구현합니다

product.kyobobook.co.kr

 

[AWS] Nginx HTTPS 적용하기

1. 도입 배경 현재 AWS로 EC2를 통해 API 프로젝트를 배포중이다. Front에서 서버로 요청할 때, CORS 에러가 발생하였고 이를 해결하고 나니 브라우저에서 다음과 같은 에러가 발생하였다. 서버는 http

readinggeneral.tistory.com

 

10분만에 끝내는 EC2 생성, NGINX 구성, SSL적용

이 포스팅에선 이론적인 내용에 보다는 구성 방법과 흐름에 대해서만 조망합니다. EC2 생성, NGINX 설치, 프록시 설정, 도메인 및 SSL 적용을 해본 적이 없거나 과정에 대해 모호한 부분이 있으시다

creampuffy.tistory.com