이전에 EC2 인스턴스
에 pm2
로 Next.js
배포하는법을 정리한적이 있었는데, 이번에는 Github-Actions
, S3
, CodeDeploy
를 이용해서 해당 pm2
로 배포한 NextJS
프로젝트의 CI/CD
를 구축해보려한다.
플로우는 아래와 같다.
push
혹은 merge
시에 Github-Actions
의해 Next.js
를 build
후 압축하여 S3
에 업로드함CodeDeploy
가 미리 작성해둔 appspec.yml
파일의 설정에 맞춰 S3
에 있는 빌드파일을 EC2
로 가져옴deploy.sh
스크립트를 실행하여 pm2
의 ecosystem.config.js
설정을 실행하여 프로젝트의 변경사항을 감지하고 배포함AWS S3
에 들어가 빌드된 프로젝트를 올릴 버킷
을 생성해 준다.
다음으로는 AWS IAM
에 들어가 EC2 인스턴스
에 할당해줄 아래의 정책을 추가한 역할
을 생성해준다.
생성 후 EC2
-> 보안 -> IAM 역할수정에 들어가 앞에서 생성한 IAM
역할을 지정해준다.
추가로 Code Deploy
에 할당해줄 역할
도 생성해준다.
AWS Code Deploy
에 들어가 아래와 같이 애플리케이션
을 생성해준다.
이어서 배포 그룹
도 생성해준다. 서비스 역할
은 앞에서 생성한 Code Deploy 역할
을 선택해준다.
황경에는 타겟 EC2 인스턴스
를 선택해주고, Load Balancer
는 비활성화 해주도록한다.
이제 Github-Actions
에서 AWS
에 접근해야하는데 이 때 Access Key
와 Secret Access Key
가 있어야 접근할 수 있으므로 다음과 같이 IAM 사용자
를 생성해준다.
이제 key
들을 발급받아 아래와 같이 repository secret key
에 등록해준다.
(여기서 AWS_REGION은 ap-northease-2, 아시아태평양 - 서울 이다.)
아래의 명령어를 통해 EC2
에 Codedeploy agent
를 설치해준다.
$ sudo apt update
$ sudo apt install ruby-full
$ sudo apt install wget
$ wget https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install
$ chmod +x ./install
$ sudo ./install auto
아래의 명령어로 잘 설치되었고, 동작하는지 확인할 수 있다
$ sudo service codedeploy-agent status
이제 Github-Actions
에 대한 스크립트를 .github/workflows/main.yml
에 작성한다.
# .github/workflows/main.yml
name: main
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Git Checkout # Git Checkout
uses: actions/checkout@v3
- name: Check Node v # 노드 버전 확인.
run: node -v
- name: Install Dependencies # 의존성 설치
run: yarn install --frozen-lockfile
- name: Build # 빌드
run: yarn build
- name: zip create # S3에 업로드할 zip 파일 생성
run: zip -qq -r ./hoon-build.zip .
shell: bash
# -qq: quit 모드로 실행 (에러나 경고메세지만 출력하도록 함)
# -r: 지정된 디렉토리를 재귀적으로 압축 (하위 디렉토리와 파일들 모두 압축)
- name: Configure AWS credentials # AWS 인증 확인
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Upload to S3 # zip 파일을 S3에 업로드
run: |
aws s3 cp --region ap-northeast-2 ./hoon-build.zip s3://{{AWS S3 bucket명}}/hoon-build.zip
- name: Code Deploy # S3에 올라간 zip 파일을 CodeDeploy로 가져옴
run: aws deploy create-deployment
--application-name {{CodeDeploy 어플리케이션 이름}}
--deployment-config-name CodeDeployDefault.AllAtOnce # CodeDeploy에서 설정한 배포 설정
--deployment-group-name {{CodeDeploy 배포 그룹 이름}}
--s3-location bucket={{AWS S3 bucket명}},bundleType=zip # Code Deploy가 S3에서 프로젝트를 찾을 수 있도록 경로 지정. (bucket=버킷 이름/test-build.zip)
appspec.yml
파일은 code-deploy
가 실행할 스크립트이다. S3
로 부터 프로젝트를 EC2 인스턴스
의 지정한 경로로 가져와 지정한 shell script
를 실행한다.
version: 0.0
os: linux # Ubuntu니까 linux로 설정.
files:
- source: /
destination: /home/ubuntu/deploy # EC2 인스턴스 안에 프로젝트를 저장할 경로.
overwrite: yes
permissions: # EC2 인스턴스에 프로젝트를 저장하기 위한 권한 설정.
- object: /home/ubuntu/deploy # EC2 인스턴스 안에 프로젝트를 저장할 경로.
owner: ubuntu
group: ubuntu
mode: 755
hooks:
AfterInstall: # 배포 완료 후 실행할 동작 설정.
- location: ./deploy.sh # deploy.sh를 실행.
timeout: 60 # 제한 시간 1000초 으로 설정. 1000초가 넘어가면 실패함.
runas: ubuntu # ubuntu 권한으로 실행.
pm2
로 프로젝트를 실행할거기 때문에 pm2
의 설정을 작성할 ecosystem.config.js
를 아래와 같이 작성해준다.
module.exports = {
apps: [
{
name: "hoon-server", // 앱의 이름
script: "./node_modules/next/dist/bin/next", // Next.js 스크립트 경로
args: "start", // Next.js 앱을 시작할 때 사용할 인수
exec_mode: "cluster", // 실행 모드: cluster 또는 fork 중 선택
instances: "2", // 클러스터 모드에서 실행할 인스턴스 수 (CPU 코어 수만큼)
autorestart: true, // 프로세스 자동 재시작 활성화
watch: true, // 파일 변경 감지 활성화 (개발 중에만 활용)
max_memory_restart: "1G", // 1GB 이상 메모리 사용 시 재시작
env: {
NODE_ENV: "production", // Node.js 환경 설정
},
},
],
};
또한, 해당 설정을 실행하기 위해 package.json
에 script
를 추가해준다.
{
...
"script": {
...
"deploy": "pm2 start ecosystem.config.js --env production",
...
}
}
이제 마지막으로 appspec.yml
파일에 의해 실행될 deploy.sh
이다. 해당 경로로 이동해 위에서 작성한 ecosystem.config.js
를 실행하는 script
인 yarn deploy
를 실행해준다.
REPOSITORY=/home/ubuntu/deploy
cd $REPOSITORY
yarn deploy
이제 로컬에서 git 타겟 브랜치
에 push
혹은 merge
시에 아래와 같은 화면을 확인할 수 있다.
아래와 같이 안녕하세요~! 를 추가한 부분이 자동으로 잘 반영된것을 볼 수 있다.
이전에 해당 작업을 했을때 따로 정리를 안해둬서 오랜만에 AWS
관련 내용을 정리하면서 해볼려니까 이슈가 조금 있었다...
code-deploy
에 대한 에러로그는 아래의 명령어로 확인할 수 있다.
$ cat /var/log/aws/codedeploy-agent/codedeploy-agent.log
처음에 역할을 잘 못 지정해서 이슈가있었는데 aws
에 역할 변경 후 EC2 인스턴스
에서도 아래의 명령어를통해 reset
시켜주었다.
# AWS 자격증명 파일 삭제
$ sudo rm -rf /root/.aws/credentials
# codedeploy-agent 재시작
$ sudo service codedeploy-agent restart
아무래도 프리티어 버전의 EC2 인스턴스
를 사용하니까 디스크 공간
이 모잘라서 계속 에러가 났었다. 아래의 명령어를 통해 디스크 공간
을 확인하고 부족하면 EC2 의 EBS 공간
을 늘려주자.
# 디스크공간 확인
$ df -h
deploy.sh
스크립트를 실행하는 과정에서 pm2 command
를 찾지 못해 pm2
의 경로를 찾아 /usr/bin/pm2
/usr/local/bin/pm2
에 심볼릭 링크
를 지정해주었다.
which pm2
sudo ln -s {which pm2} /usr/bin/pm2
sudo ln -s {which pm2} /usr/local/bin/pm2