개념적인 부분은
Git Action 개념 정리 참고
Git Action / CodeDeploy CI/CD
위 게시글을 참고하면 좋을듯 하다.
현재 aws EC2 인스턴스에 올라가있는 레파지토리에서 master 브랜치에 push가 이루어 졌을때 개발망 서버에 자동 배포하도록 하는 기능을 적용해 보았다.
먼저 레파지토리 설정에서 환경변수 등 프로젝트에 쓰이는 민감한 정보들은 (like .env) secrets에 등록해 준다
프로젝트에 .github/workflows 폴더를 생성하고 아래에 .yml 파일을 생성한다.
name: Deploy To EC2
on:
push:
branches: ["master"]
#env는 해당 작업이 실행되면서 쓰이는 환경 변수에 해당한다. 앞에 $를 붙여 사용한다 ex) s3://$BUCKET_NAME/$PROJECT_NAME/$GITHUB_SHA.zip
env:
PROJECT_NAME: ~ # s3 bucket에 폴더 이름
BUCKET_NAME: ~ # s3 bucket 이름
CODE_DEPLOY_APP_NAME: ~ # aws CodeDeploy서비스에 생성된 어플리케이션 이름
DEPLOYMENT_GROUP_NAME: ~ # 어플리케이션에 등록된 배포 그룹 이름
jobs:
deployment:
runs-on: ubuntu-22.04 #작업이 실행될 환경 지정
timeout-minutes: 10 #작업이 실행될 타임아웃 지정 타임아웃시간이 초과되면 작업이 중지됨
steps: # 작업을 순차적으로 진행
- name: Checkout # name 각 단계에서 작업 이름 설정으로 작업과 직접적인 관련은 없음
uses: actions/checkout@v3 # uses 어떤 액션을 사용할지 지정 / checkout@v3 는 현재 레포지토리의 소스코드를 체크아웃하는 데 사용
- name: Install Libraries
run: npm ci # run 터미널 명령어 실행 / 프로젝트에 필요한 라이브러리 설치 (package-lock.json)
- name: Setup Node
uses: actions/setup-node@v3 # Node.js 환경을 설정하는데 사용 (최신버전 v3)
with:
node-version: "18" #노드 버전 지정
- name: Create Env File
run: | # | : 리터럴 스타일 개행 또는 들여쓰기 유지
touch .env
echo '${{ secrets.ENV }}' >> .env
# 환경변수나 프로젝트에 사용되는 프라이빗한 정보들을 레파지토리 secrets에 등록하고 해당 정보를 사용하여 .env파일을 생성
- name: Build
run: npm run build # 프로젝트 빌드
- name: Make Zip File
run: zip -qq -r ./$GITHUB_SHA.zip . #현재 작업 디렉토리 파일 압축 / -qq : 출력 메세지 최소화 옵션 / -r 디렉토리 내부 모든 파일 및 디렉토리 전부 압축 / $GITHUB_SHA : 현재 커밋의 SHA 해시값 이름으로 압축 / 마지막 . 은 현재 폴더를 의미
shell: bash # 해당 명령어를 Bash에서 실행
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1 # AWS 자격 증명을 구성
with: # 자격 증명에 필요한 정보
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_PRIVATE_ACCESS_KEY }}
aws-region: ap-northeast-2
- name: Upload to S3
run: aws s3 cp --region ap-northeast-2 ./$GITHUB_SHA.zip s3://$BUCKET_NAME/$PROJECT_NAME/$GITHUB_SHA.zip
# s3 해당 경로에 앞서 압축한 빌드된 프로젝트를 복사
- name: Code Deploy To EC2 instance
run: aws deploy create-deployment # CodeDeploy를 통해 Ec2 인스턴스로 코드를 배포
--application-name $CODE_DEPLOY_APP_NAME # CodeDeploy 어플리케이션 이름
--deployment-config-name CodeDeployDefault.AllAtOnce # 연결된 모든 인스턴스에 동시에 배포를 설정하는 파라미터
--deployment-group-name $DEPLOYMENT_GROUP_NAME # 배포그룹 이름 지정
--s3-location bucket=$BUCKET_NAME,bundleType=zip,key=$PROJECT_NAME/$GITHUB_SHA.zip # 앞에서 복사해놓은 프로젝트 압축파일을 가져와 배포
appspec.yml 파일 생성 CodeDeploy -> EC2 의 작업을 담당하는 소스코드 인듯 하다 파일 위치는 프로젝트 루트 폴더이다.
#appspec.yml
version: 0.0
os: linux
files:
- source: /
destination: /home/ubuntu/booth-server
permissions: #권한 설정
- object: /home/ubuntu/booth-server/
owner: ubuntu
group: ubuntu
hooks:
AfterInstall: #EC2에 설치 후 작업
- location: scripts/deploy.sh #인스톨 후 생성된 실행파일 실행 / 아래 파일 참고
timeout: 60
runas: ubuntu
# git 프로젝트 최상위 경로에서 scripts/deploy.sh 파일
#!/bin/bash
cd /home/ubuntu/booth-server
# pm2 list 명령어 출력을 변수에 저장
pm2_list=$(pm2 list)
echo "$pm2_list"
if echo "$pm2_list" | grep -q "main"; then
# 이미 실행 중이면 로드
echo "main.js is already running. Reloading..."
pm2 restart main
else
# 실행 중이 아니면 시작
echo "main.js is not running. Starting..."
pm2 start dist/main.js
fi
pm2 save