Dev

github action을 통한 ci cd 자동화(feat. shell script)

hou27 2022. 10. 17. 19:45

프로젝트를 진행하면서 CI / CD의 자동화 필요성을 절실하게 느끼게 되었다.

다른 것도 많았지만 기본적으로 github를 사용하고 있다보니

자연스레 github action을 사용해보자라고 생각했던 것 같다.


여기서 CI / CD 란 무엇일까?

필자가 자동화의 필요성을 절실하게 느낀 것처럼

매번 개발자가 코드를 수정하고 직접 빌드 및 테스트를 하고 배포까지 하게 된다면

그 시간 비용은 엄청날 것이다.

때문에 CI / CD의 개념을 알고 도입하는 것이 필요하다.

CI

: 빌드와 테스트를 자동화하는 것

지속적 통합(Continuous Integration)

CD

: 배포 과정을 자동화하는 것

지속적 서비스 제공(Continuous Delivery) or 지속적 배포(Continuous Deployment)


 

전체적인 flow는 다음과 같다.

STEP 1

CI - docker image build 및 docker hub에 push(아직 테스트는 미비한 상황)

STEP 2

CD - ec2에서 돌아가도록 설정한 application runner를 통해 내부의 쉘 스크립트를 실행하도록 함.

ec2에 만들어 둔 쉘 스크립트의 역할

  • 기존 컨테이너와 이미지 삭제
  • docker hub에서 최신 버전의 이미지 pull
  • 해당 이미지를 사용하여 다시 ec2 인스턴스에서 docker compose 컨테이너 생성 및 실행

보통이라면 대부분의 branch에 CI를 적용하고,
각 브랜치에 코드가 push될 때마다 build, test, lint 등을 진행하겠지만
현재 프로젝트 전반적으로 테스트가 미비해서 develop 브랜치 및 main 브랜치에만 CI가 적용되어있다.

 

STEP 1 상세보기

Build Docker image and Push to Docker Hub

github action Job 1 -- CI 부분

name: Docker Image CI
runs-on: ubuntu-latest

steps:
  - name: Checkout
    uses: actions/checkout@v3

  - name: Login to DockerHub
    uses: docker/login-action@v2.0.0
    with:
      username: ${{secrets.DOCKERHUB_USERNAME}}
      password: ${{secrets.DOCKERHUB_TOKEN}}

  - name: Build and push Docker images
    uses: docker/build-push-action@v3.1.1
    with:
      context: .
      tags: hou27/quickchive_backend:latest
      # build on feature branches, push only on develop branch
      push: ${{ github.ref == 'refs/heads/develop' }}

github의 기본 ubuntu runner 위에서 실행하였다.

 

STEP 2 상세보기

github action Job 2

name: Deploy to EC2
runs-on: quickchive-server

steps:
  - name: executing remote ssh commands using password
    uses: appleboy/ssh-action@master
    with:
      host: ${{ secrets.HOST }}
      username: ubuntu
      key: ${{ secrets.KEY_PAIR }}
      script: |
        sh /home/ubuntu/actions-runner/deploy.sh

배포용 ec2를 runner로 설정하여 실행하였다.
(Setting - Actions - Runners - New self-hosted runner 과정을 거쳐 생성)

AWS EC2에 설정해둔 파일들

deploy.sh

# !/bin/bash
docker ps -a | grep quickchive_backend:latest | awk '{print$1}' | xargs -t -I % docker rm -f % && docker image ls | grep quickchive | awk '{print$3}' | xargs -I % docker rmi %
cd ~ubuntu && docker-compose up -d
  • ec2 인스턴스 내에 스크립트 파일 생성
    이전 버전의 docker container와 docker image를 삭제한 후 docker hub에 job1을 통해 업로드한 image를 pull하여
    해당 이미지를 사용하여 다시 ec2 인스턴스에서 docker compose 컨테이너를 생성 및 실행한다.

 

전체 github action workflow를 정의한 파일

ci-cd.yml

name: Docker Image CI && Deploy to EC2

on:
  push:
    branches: ['develop']

jobs:
  job1:
    name: Docker Image CI
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Login to DockerHub
        uses: docker/login-action@v2.0.0
        with:
          username: ${{secrets.DOCKERHUB_USERNAME}}
          password: ${{secrets.DOCKERHUB_TOKEN}}

      - name: Build and push Docker images
        uses: docker/build-push-action@v3.1.1
        with:
          context: .
          tags: hou27/quickchive_backend:latest
          # build on feature branches, push only on develop branch
          push: ${{ github.ref == 'refs/heads/develop' }}
  job2:
    needs: job1
    name: Deploy to EC2
    runs-on: quickchive-server

    steps:
      - name: executing remote ssh commands using password
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.HOST }}
          username: ubuntu
          key: ${{ secrets.KEY_PAIR }}
          script: |
            sh /home/ubuntu/actions-runner/deploy.sh

'Dev' 카테고리의 다른 글

HA(고가용성)와 DR(재해 복구)  (0) 2022.11.19
Docker timezone 설정하기  (0) 2022.10.19
Intellij 단축키 정복하기  (0) 2022.05.22
Singleton Pattern(싱글톤 패턴)  (2) 2022.05.10
Dependency Injection(의존성 주입 - DI)란?  (0) 2022.05.07