본문 바로가기
Frontend/React

[React] PM2를 활용한 EC2에 React 무중단 배포

by chickenman 2024. 10. 13.

Github Action과 AWS Codedeploy를 활용한 React 어플리케이션의 CICD 파이프라인을 구축하고 있었다. 

현재 구상중인 어플리케이션의 구조상에서 Front는 React로만 구성되었다. 

 

EC2에 접속하여 yarn start / npm start와 같이 React를 실행해주면, EC2와 연결되어 있는 상태에서는 EC2 public domain 및 port를 사용하여 접속할 수 있지만 연결(접속)을 끊으면 어플리케이션이 중단된다.

그에 따라 개발자는 EC2의 under level에서 react가 돌아갈 수 있게끔해야 한다. 

 

또한, 단순 패키지 매니저들을 사용하여 어플리케이션을 실행하면 다운타임이 반드시 발생한다. 운영 서비스에서 다운 타임이 발생하는 문제는 치명적임으로 이를 고려하여 CD 라인을 구축해야 한다.

 

Nginx, S3 활용 등 여러가지 방법이 있지만 본인은 React 및 Front 생태계에 대해 아직 잘 알지 못하고 있다고 판단하고 EC2에서 pm2를 활용하는 방법을 채택하였다. 

 

초기에는 pm2에 대해서 간략하게 조사하였을 때 아래와 같은 형태의 코드를 사용해왔다.

 pm2 start yarn -i 2 --name app -- start
 
 pm2 reload app

pm2 공식 사이트를 방문해 보니, cluster mode를 활용하고 reload를 사용한다면 무중단 배포가 가능하다고 나와 있었다.

 

그런데 막상 위와 같은 방식으로 테스트해보면, reload 과정에서 지속적으로 website 접속을 시도할 때 1초 정도의 down-time이 발생한다. 

그리고 간혹가다 reload 과정에서 계속 접근을 시도하면 어플리케이션 자체가 실행되지 못하고 죽어서 website에는 접속할 없지만 pm2 status 상태는 online으로 표기되는 이상한 오류가 있다. (버그인 것 같다. 만약 restart max에 도달하여 어플리케이션 실행을 실패하면 error로 표기된다.)

 

그래서 pm2상에서 이런 문제를 해결해줄 수 있는 graceful-start를 사용해보려고 해도, 단순 React 어플리케이션이기 때문에 Ready 메세지를 보내줄 타이밍을 잡기 어렵다.

https://pm2.keymetrics.io/docs/usage/signals-clean-restart/#graceful-start

 

그래서 공식 문서를 찾아보다 보니 static content를 배포해줄 수 있는 방법을 찾았다. (사실 문서를 꼼꼼히 읽어보지 않았어서 오래 걸렸다..ㅠ)

본인이 구상했던 Front 서버는 static content인 React만을 배포해주면 되었기 때문에, pm2의 이 방식을 사용하였고 그 결과는 성공이었다.

또한, React는 Single Page Application으로, pm2 server 명령어에 --spa 옵션을 추가하여 모든 요청을 index.html로 redirect 해주도록 하였다.

https://pm2.keymetrics.io/docs/usage/expose/

pm2 serve <react가 build되어 있는 path> <port>

pm2 reload app이름

Ex) pm2 serve build 3000

 

 

그렇게 해서 완성하게 된 나의 deploy shell script는 아래와 같다.

if pm2 list | grep -q "app"; then
    echo "Application is running. Reloading start..."
    pm2 reload app
else
  echo "Application is not running. Start Appllication..."
  pm2 serve --name app build 3000 --spa
fi

 

 

앞으로 서두르지말고 더욱 꼼꼼히 공식 문서를 읽어보자.