⚡️ 목표 : NestJS Framework를 사용한 Project를 Github Actions tool과 AWS CodeDeploy를 사용하여 자동 배포 하기
자동 배포의 Flow는 크게 아래의 그림과 같다.
Framework : NestJS
서버 환경 : Node.js
EC2 server : ubuntu LTS 20.04(프리티어)
CD tool : Github Actions, AWS CodeDeploy
Storage : Amazon S3
local OS : window(power shell)
etc : PM2
sudo apt update
sudo apt install npm
sudo apt install nodejs npm
node -v
→ 10 버전이 깔려서 다시 시도
sudo apt-get update
sudo apt-get install nodejs -y
→ v18.17.1이 잘 설치됨. 조금 달라도 괜찮지만 꼭 18로 할 것
npm install -g @nestjs/cli
sudo npm install pm2@latest -g
sudo apt install ruby-full
sudo apt install wget
cd /home/ubuntu
wget https://bucket-name.s3.region-identifier.amazonaws.com/latest/install
name: Deploy to Amazon EC2
on:
push:
branches:
- main
# 본인이 설정한 값을 여기서 채워넣습니다.
# 리전, 버킷 이름, CodeDeploy 앱 이름, CodeDeploy 배포 그룹 이름
env:
AWS_REGION: ap-northeast-2
S3_BUCKET_NAME: togethereat-s3-bucket
CODE_DEPLOY_APPLICATION_NAME: togethereatdeploy
CODE_DEPLOY_DEPLOYMENT_GROUP_NAME: togethereat-deploy-group
permissions:
contents: read
jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
environment: production
steps:
# (1) 기본 체크아웃
- name: Checkout
uses: actions/checkout@v3
# (2) Node.js 세팅
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '18.17.1'
# (3) build (Test 제외)
- name: Install dependencies
run: npm install
# (4) AWS 인증 (IAM 사용자 Access Key, Secret Key 활용)
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
# (5) 빌드 결과물을 S3 버킷에 업로드
- name: Upload to AWS S3
run: |
aws deploy push \
--application-name ${{ env.CODE_DEPLOY_APPLICATION_NAME }} \
--ignore-hidden-files \
--s3-location s3://$S3_BUCKET_NAME/$GITHUB_SHA.zip \
--source .
# (6) S3 버킷에 있는 파일을 대상으로 CodeDeploy 실행
- name: Deploy to AWS EC2 from S3
run: |
aws deploy create-deployment \
--application-name ${{ env.CODE_DEPLOY_APPLICATION_NAME }} \
--deployment-config-name CodeDeployDefault.AllAtOnce \
--deployment-group-name ${{ env.CODE_DEPLOY_DEPLOYMENT_GROUP_NAME }} \
--s3-location bucket=$S3_BUCKET_NAME,key=$GITHUB_SHA.zip,bundleType=zip
version: 0.0
os: linux
files:
- source: /
destination: /home/ubuntu/app
overwrite: yes
permissions:
- object: /
pattern: "**"
owner: ubuntu
group: ubuntu
hooks:
ApplicationStart:
- location: scripts/start.sh
timeout: 60
runas: ubuntu
#!/usr/bin/env bash
PROJECT_ROOT="/home/ubuntu/app"
APP_NAME="project"
TIME_NOW=$(date +%c)
cd $PROJECT_ROOT
pm2 delete $APP_NAME
pm2 start npm --name $APP_NAME -- run start:dev
echo "$TIME_NOW > Deploy has been completed"
: 해당 프로젝트는 HotReloaded 패키지를 설치하여 기본 서버 실행 명령어는 npm run start:dev이기 때문에 저렇게 해주었다.
section 1~3까지 모두 실행시킨 후 flow를 확인하면서 따라가 보자
순차적으로 실행되는 것을 볼 수 있다.
S3 압축파일 확인
AWS CodeDeploy 배포 성공 했는지 확인
ubuntu 서버에서 실행 되고 있는지 확인
pm2 list (pm2로 실행되고 있는 프로젝트 확인)
pm2 log (pm2로 실행된 프로젝트의 로그들 확인)
ls (해당 디렉터리 모든 파일 확인)
ls -a (해당 디렉터리 숨김폴더 및 숨김파일 포함 모두 확인)
cd ~ (default root로 이동)
cd .. (상위 폴더로 이동)
cd 폴더이름 (폴더이름으로 이동)
1) .env 파일 없음으로 에러
touch .env (.env 파일 생성)
vim .env (.env 파일 내용 작성)
cat .env (.env 파일 읽기)
2) EC2와 CodeDeploy 실행 지연
NestJS로 만든 프로젝트는 express에 비해 무겁고 실행속도가 느려 local에서도 첫 빌드 시 오래 걸린적이 있다.
대여한 EC2 서버가 아무래도 프리티어다 보니 여러 번 파일을 받고 덮어쓰고 실행하다 보니 멈추기도 하고 CodeDeploy 실행이 느려지기도 했다.
이 부분은 EC2를 다시 재부팅해준 뒤 재 실행했더니 조금 나아졌다.
3) 반 자동으로 실행
나중에는 EC에 파일은 잘 받아졌으나 빌드하는데 오랜시간이 걸려 start.sh가 제대로 실행이 되지 않는 일이이 생겼다.
EC2 모니터링을 해보니 CPU가 70~80%를 사용하고 있다는 것이 보였다.
그래서 처리한 방법은 다음과 같다.
3-1) main에 push 또는 pull request 이벤트가 일어났을 때 변경된 파일이 S3 → EC2로 잘 받아진 것을 확인한 뒤 서버를 재부팅한다.
3-2) cd app폴더로 들어가서
pm2 start npm --name app -- run start:dev 실행
이렇게 되면 변경된 사항을 자동으로 받을 수 있고, pm2를 사용해 계속해서 서버를 켜 놓을 수 있다.
덩치가 큰 NestJS를 사용하다 보니 서버에 과부하가 많이걸려 완전 자동화는 이루어 내지 못했다.
Docker가 프로젝트를 이미지화 하여 서버를 실행시킬 수 있다고 하는데 Docker에 대해 공부한 뒤 해당 project에 적용해 볼 예정이다.
배포를 할 수 있게 도와주신 O님, B님, J님 감사합니다👍🚀