프로젝트의 루트 디렉터리에서 .github/workflows 디렉터리를 생성해줍니다.
workflows 디렉터리 내부에 main.yml 파일을 생성합니다.
name: CI/CD Docker
# 트리거를 수행할 브랜치를 지정합니다.
on:
push:
branches: [main]
# 환경설정
env:
AWS_REGION: ap-northeast-2
ECR_REGISTRY: ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.ap-northeast-2.amazonaws.com
VERSION: ${{ github.sha }}
IMAGE_NAME: moneynote
CONTAINER_NAME: moneynote-server
jobs:
# test job
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Node.js Setup
uses: actions/setup-node@v4
with:
node-version: 21.7.3
cache: 'npm'
- run: npm install
- run: npm run test
# build job
build:
needs: test # test 성공 후에 실행되도록 정의
runs-on: ubuntu-latest
steps:
# aws에 로그인 후 ECR에 푸시
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Login too Amazon ECR
run: aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin ${{ env.ECR_REGISTRY }}
- name: Build, tag, and push image to Amazon ECR
run: |
docker build -t ${{ env.IMAGE_NAME }}:latest .
docker tag ${{ env.IMAGE_NAME }}:latest ${{ env.ECR_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
docker push ${{ env.ECR_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
# 배포 Job
deploy:
needs: build # build 후에 실행되도록 정의
runs-on: [self-hosted, moneynote] # AWS ./configure에서 사용할 label명
steps:
# 80번 포트와 컨테이너 3000포트 연결
- name: Pull image and run
run: |
docker pull ${{ env.ECR_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
docker stop ${{ env.CONTAINER_NAME }} || true
docker rm ${{ env.CONTAINER_NAME }} || true
docker rmi ${{ env.ECR_REGISTRY }}/${{ env.IMAGE_NAME }}:latest || true
docker run -d -p 80:3000 \
--network="host" \
--env-file /home/ubuntu/moneynote-BE/.production.env \
--name ${{ env.CONTAINER_NAME }} \
--restart always ${{ env.ECR_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
GitHubActions의 Workflow는 test -> build -> deploy 순서로 진행되며 각 단계에서 성공해야 다음 단계로 넘어갈 수 있습니다.
main.yml 내에 작성한 ${{ env.??? }}는 main.yml에서 환경 설정해준 env 값을 가져옵니다. env: 내부에 ${{ env.??? }}를 사용할 수 없습니다.
on
: push 이벤트가 main branch에 발생했을 때, 이 워크플로우가 실행되도록 설정합니다.
env
: 전역적으로 사용될 환경 변수를 설정합니다.
jobs
: 워크플로우 내에서 실행되는 작업 단위입니다. test, build, deploy 과정을 포함하고 있습니다.
test
: 코드 테스트를 수행하는 Job입니다.runs-on
: GitHub Actions 러너가 실행될 가상 환경(Ubuntu 최신 버전)을 지정합니다.uses
: actions/checkout@v4 저장소 코드를 체크아웃합니다.uses
: actions/setup-node@v4 Node.js를 설정합니다. 여기서는 특정 버전을 설치하고 npm 캐시를 활성화합니다.run
: 의존성 설치와 테스트 스크립트를 실행합니다.build
: 테스트가 성공한 후 실행되며 이미지를 빌드하고 ECR로 푸시합니다.needs
: test job이 성공적으로 완료된 후에 실행합니다.uses
: actions/checkout@v4 최신 코드를 가져옵니다.uses
: aws-actions/configure-aws-credentials@v4 AWS 자격증명을 구성합니다. 액세스 키와 시크릿 키를 사용합니다.run
: ECR 로그인 후, Docker 이미지를 빌드, 태그 지정, 푸시합니다.deploy
: 빌드된 Docker 이미지를 실제 서버에 배포합니다.needs
: build job이 성공적으로 완료된 후에 실행합니다.steps
: 작업을 수행하는 단계들의 목록입니다.run
: 먼저 최신 이미지를 ECR에서 pull하고, 기존에 실행 중인 컨테이너를 중지 및 제거합니다. 이후 새 이미지를 이용해 컨테이너를 실행합니다. 실행 시 80번 포트를 내부의 3000포트와 연결하고, 호스트 네트워크 모드를 사용하여 네트워크 설정을 수행합니다.초간단 docker 설치입니다. ubuntu 사용자들은 차례대로 붙여 넣으면 됩니다.
# 우분투 패키지 업데이트
sudo apt-get update
# using https for download
sudo apt-get install -y apt-transport-https
# https certification
sudo apt-get install -y ca-certificates
# https url file transfer protocol
sudo apt-get install -y curl
# repository register
sudo apt-get install -y software-properties-common
# 공식 GPG key 추가
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# GPG key 확인
sudo apt-key fingerprint
# Docker 공식 apt 저장소 추가
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
# check list (ubuntu version에 따라 없을 수도 있음)
sudo grep docker /etc/apt/sources.list
# 시스템 패키지 업데이트
sudo apt-get update
# docker 설치
sudo apt-get install -y docker-ce
# docker 설치 확인
sudo docker --version
sudo systemctl status docker
github 본인의 repository의 Settings 탭에서 Actions > Runners를 선택합니다.
New self-hosted runner를 선택하고, Linux를 선택합니다.
EC2에 접속하여 Download 부분을 차례대로 EC2 터미널에 붙여 넣습니다.
./config.sh 문을 실행하면 다음과 같은 입력을 요청합니다.
runs-on: [self-hosted, moneynote]
에서 moneynote 대신 여러분의 프로젝트 이름을 작성하면됩니다.)swagger 문서에서 '인증'을 '인증/인가'로 수정하겠습니다.
소스코드를 수정하고 repository에 push 해보겠습니다.
현재 아래와 같은 swagger문서를 볼 수 있습니다.
test, build를 거쳐 deploy에서 멈춰 있는 것을 확인할 수 있습니다.
EC2에 접속하여 ./run.sh
명령어를 실행해줍니다.
Job deploy completed with result: Succeeded 라는 문구가 뜨면 배포가 완료된 것을 확인할 수 있습니다. Ctrl+c 로 종료합니다.
ECR에 새로운 이미지가 push 되었습니다.
swagger 문서의 제목이 '인증/인가'로 변경되었음을 확인할 수 있습니다.
주의
EC2에서 처음 이미지를 pull 받아서 컨테이너를 실행시킨 상태에서 CI/CD 파이프라인을 실행해야합니다. 컨테이너가 없거나 실행 중이 아니라면 에러가 발생할 수 있습니다.