GitHubAction CI/CD 파이프 라인 구축, 자동 배포 테스트

허창원·2024년 5월 7일
0
post-custom-banner

CI/CD 워크플로우 작성

프로젝트의 루트 디렉터리에서 .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.??? }}를 사용할 수 없습니다.

GitHubActions의 Workflow 구성

  • on : push 이벤트가 main branch에 발생했을 때, 이 워크플로우가 실행되도록 설정합니다.

  • env : 전역적으로 사용될 환경 변수를 설정합니다.

  • jobs : 워크플로우 내에서 실행되는 작업 단위입니다. test, build, deploy 과정을 포함하고 있습니다.

jobs 설명

Test Job

  • test: 코드 테스트를 수행하는 Job입니다.
    • runs-on: GitHub Actions 러너가 실행될 가상 환경(Ubuntu 최신 버전)을 지정합니다.
      • uses: actions/checkout@v4 저장소 코드를 체크아웃합니다.
      • uses: actions/setup-node@v4 Node.js를 설정합니다. 여기서는 특정 버전을 설치하고 npm 캐시를 활성화합니다.
      • run: 의존성 설치와 테스트 스크립트를 실행합니다.

Build Job

  • build: 테스트가 성공한 후 실행되며 이미지를 빌드하고 ECR로 푸시합니다.
    • needs: test job이 성공적으로 완료된 후에 실행합니다.
      • uses: actions/checkout@v4 최신 코드를 가져옵니다.
      • uses: aws-actions/configure-aws-credentials@v4 AWS 자격증명을 구성합니다. 액세스 키와 시크릿 키를 사용합니다.
      • run: ECR 로그인 후, Docker 이미지를 빌드, 태그 지정, 푸시합니다.

Deploy Job

  • deploy: 빌드된 Docker 이미지를 실제 서버에 배포합니다.
    • needs: build job이 성공적으로 완료된 후에 실행합니다.
    • steps: 작업을 수행하는 단계들의 목록입니다.
      • run: 먼저 최신 이미지를 ECR에서 pull하고, 기존에 실행 중인 컨테이너를 중지 및 제거합니다. 이후 새 이미지를 이용해 컨테이너를 실행합니다. 실행 시 80번 포트를 내부의 3000포트와 연결하고, 호스트 네트워크 모드를 사용하여 네트워크 설정을 수행합니다.

EC2에 Docker 설치

초간단 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

EC2에 GitHubRunner 설치

github 본인의 repository의 Settings 탭에서 Actions > Runners를 선택합니다.
New self-hosted runner를 선택하고, Linux를 선택합니다.

EC2에 접속하여 Download 부분을 차례대로 EC2 터미널에 붙여 넣습니다.

./config.sh 문을 실행하면 다음과 같은 입력을 요청합니다.

  • Enter the name of the runner group to add runner ro: Enter
  • Enter the name of runner: Enter
  • Enter any additional label: moneynote
    (main.yml에 작성한 runs-on: [self-hosted, moneynote]에서 moneynote 대신 여러분의 프로젝트 이름을 작성하면됩니다.)
  • Enter the name of work folder: Enter

자동 배포 테스트

swagger 문서에서 '인증'을 '인증/인가'로 수정하겠습니다.

소스코드를 수정하고 repository에 push 해보겠습니다.

Before

현재 아래와 같은 swagger문서를 볼 수 있습니다.

test, build를 거쳐 deploy에서 멈춰 있는 것을 확인할 수 있습니다.

EC2에 접속하여 ./run.sh 명령어를 실행해줍니다.
Job deploy completed with result: Succeeded 라는 문구가 뜨면 배포가 완료된 것을 확인할 수 있습니다. Ctrl+c 로 종료합니다.

After

ECR에 새로운 이미지가 push 되었습니다.

swagger 문서의 제목이 '인증/인가'로 변경되었음을 확인할 수 있습니다.

주의
EC2에서 처음 이미지를 pull 받아서 컨테이너를 실행시킨 상태에서 CI/CD 파이프라인을 실행해야합니다. 컨테이너가 없거나 실행 중이 아니라면 에러가 발생할 수 있습니다.

참고문헌
https://codegear.tistory.com/84

post-custom-banner

0개의 댓글