Nextjs를 github action, EC2, pm2로 CI/CD 구축하기(5)

CGH96·2023년 8월 10일
5

이번 글에서는 목표는 다음과 같다.
1. CodeDeploy 동작 정의하기
2. EC2에 pm2, nodejs 설치하기
3. Swap File을 이용해서 EC2 RAM늘려주기
4. 80번 포트로 EC2에 요청 들어오면 3000번 포트로 연견할도록 포트포워딩 해주기
5. pm2로 Nextjs App 구동시키기




CodeDeploy의 동작을 정의해보자.

CodeDeploy의 동작은 프로젝트 폴더 내에서 appspec.yml이란 파일을 통해 정의한다.
반드시 파일명은 appspec.yml이어야 한다.

AWS에는 CodeCommit, CodeBuild, CodeDeploy와 같은 서비스가 있는데 CodeBuild는 buildspec.yml을 통해 동작을 정의하고, CodeDeploy는 appspec.yml을 통해 정의한다. 파일의 위치는 프로젝트 root 폴더에 놓자.




다음과 같이 작성해주자. 아래 코드에서 hooks부분은 배포를 위한 수명 주기 이벤트마다 특정 동작들을 정의하는 것이다.
AWS 관련 공식문서 링크

version: 0.0
os: linux

files:
  - source: /
    destination: /home/ubuntu/chagok
    overwrite: yes
permissions:
  - object: /home/ubuntu/chagok
    owner: ubuntu
    group: ubuntu
    mode: 755
hooks:
  AfterInstall:
    - location: scripts/after-install.sh
      timeout: 300
      runas: root



나는 당장 정의할 동작은 없지만 이해를 위해 만들어보았다.

위와 같이 작성하고 github main브랜치에 push한다면 S3에 파일이 업로드되고 CodeDeploy가 EC2에 배포해줄 것이다.
(EC2에 배포된 것이지 웹에 배포된 것은 아니다. 웹에 배포하려면 Nextjs앱을 구동해주어야 한다)

나는 /home/ubuntu/chagok에 배포했으니 여기서 확인 할 수 있다. .next파일까지 완벽하게 존재한다.😁😁

혹시 CodeDeploy Log를 확인해보고 싶다면 다음 위치에서 확인할 수 있다.

  1. Agent Log - 전체 로그라고 생각하면 된다.
    /var/log/aws/codedeploy-agent/codedeploy-agent.log
  2. Deploy Log - hook관련 로그
    /opt/codedeploy-agent/deployment-root/deployment-logs/codedeploy-agent-deployments.log



EC2에 pm2, nodejs를 설치하자.

왜 nodejs를 설치하나 의문을 가질 수도 있는데 EC2도 컴퓨터이고, nextjs는 js로 이루어진 앱이니 실행시키려면 nodejs가 필요하다. 그리고 여기서는 생략됐지만 당연히 ssh을 통해 EC2에 로그인해주어야 한다.
Amazon EC2 인스턴스에서 Node.js 설정

## curl 설치
sudo apt-get install -y curl
sudo apt update

## nvm(노드 버전 관리자)설치
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash

## nvm활성화
. ~/.nvm/nvm.sh

## nodejs 최신 버전 설치 (`--lts`대신 버전 입력도 가능)
nvm install --lts


## 올바르게 설치됐는지 버전 확인
node -v
npm -v

## pm2 설치
npm install -g pm2




SwapFile로 EC2의 램을 늘려주자.

이제 SwapFile로 EC2의 램을 늘려주자. 아마 이 글을 보는 사람들 대부분 프리티어를 쓸 것이고, 램용량이 기껏해야 1GB정도일 것이다. 지금 이글에서는 빌드를 github action에서 하고 있지만 가끔은 EC2에서 직접 빌드할 일도 있을 것이다. 이때, 램이 1GB밖에 안된다면 빌드하다가 멈춰버릴 것이다.

SwapFile은 EC2의 저장공간을 파티션으로 나눠 가상 RAM으로 전환시켜준다.
레퍼런스

## 스왑 파일 생성 (bs=블록 크기, count=블록 수, 스왑 용량 = bs * count, 이 예제에서는 4GB)
 sudo dd if=/dev/zero of=/swapfile bs=128M count=32
 
 ## 스왑 파일의 읽기 및 쓰기 권한 업데이트
 sudo chmod 600 /swapfile
 
 ## Linux 스왑 영역 설정
 sudo mkswap /swapfile
 
 ## 스왑 공간에 스왑 파일을 추가하여 스왑 파일을 즉시 사용 할 수 있도록 함
 sudo swapon /swapfile
 
 ## 성공적인지 확인
  sudo swapon -s
  
 ##  /etc/fstab 파일을 편집하여 부팅 시 스왑 파일을 시작 - (이 부분 잘 모르겠다면 vi편집기 명령어에 대해 찾아보자)
 
 ### 편집기 열기
 sudo vi /etc/fstab
 
 ### 다음 코드를 추가
 /swapfile swap swap defaults 0 0




포트포워딩하자.

이제 포트포워딩을 해주자. 우리는 http 포트 번호인 80번 포트로 요청이 들어오면 3000번 포트로 연결해줄 것이다.
https의 경우 EC2의 로드 밸런서를 사용할 것이다. 일단 80번만 해주자.

## 포트포워딩
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3000

## 포트포워딩 테이블확인
sudo iptables -t nat -L --line-numbers

잘되었다면 다음과 같은 화면이 나올 것이다.




PM2로 NEXTJS를 구동시키자.

pm2 공식문서

## 앱 구동
cd /home/ubuntu/chagok
pm2 start "npm run start" --name chagok-fe

## 확인
pm2 list

## 그 밖의 명령어
pm2 kill => 모든 프로세스 삭제
pm2 restart [프로세스id, 이름 등] 프로세스 재시작.

그럼 이제 pm2 list를 통해 백그라운드에서 앱이 잘 실행되는 것을 볼 수 있다. pm2의 default 옵션이 파일에 변동사항이 있다면 자동으로 restart해주기 때문에 아마 코드가 변경될 때마다 변경사항이 잘 적용되어 배포될 것이다.

pm2도 옵션이 정말 많고 뭔가 특정한 동작을 하게 해주고 싶다면 ecosystem.config.js를 통해 동작을 정의할 수 있다.
하지만 일단 이건 패스하도록 하자...
궁금하다면 클릭

여기까지 했다면 아마 배포가 잘 되었을 것이다. 브라우저에서 우리가 처음에 EC2인스턴스에 연결한 탄력적IP를 통해 확인할 수 있을 것이다. 물론 프로토콜도 명시해주자. http:[IP 주소]


2개의 댓글

comment-user-thumbnail
2024년 5월 18일

감사합니다 많이 도움 되었습니다

답글 달기
comment-user-thumbnail
2024년 6월 3일

궁금한 게 있는데요.
Github Action에서 npm 패키지 다 설치하고 빌드하고,
굳이 왜 또, EC2 에서 npm 패키지 다 설치하고 실행 시키는 거예요?
빌드한 파일을 기반으로, EC2 에 배포해서 그거 실행 시키면 되는 거 아닌가요?
왜 npm 패키지를 github 랑 ec2 에서 두번 설치하는지..

답글 달기