DevOps

Github Actions와 Docker+AWS EC2를 활용한 CI/CD

Grace 2022. 11. 30. 11:12

CI/CD는 간략히 말씀드리면 우리가 작성한 코드가 하나로 합쳐질 때마다 그 코드를 반영하여 배포해주도록 하는
빌드/배포 자동화 과정입니다! 이전에는 Jenkins, TravisCI 등을 많이 사용했지만 github에서 git Actions 기능을 추가하면서 github 하나만으로도 편리하게 협업이 가능해졌습니다🙂
github Actions+ AWS S3+EC2를 활용하는 방법도 있지만 소스코드 관리를 위해 S3를 추가적으로 사용하는 것은 비용적으로 부담이 되고 우리는 이미 docker를 사용하기 때문에 docker+EC2를 사용해서 배포하는 과정을 알려드립니다.

Github Access Token을 Secret에 등록하기

github의 권한 인증이 token으로 변경된지가 벌써 꽤나 오래되었죠? 이제 github를 사용하시는 분들이라면 github access token을 모두 가지고 계실겁니다. 혹시 가지고 있지 않으신 분들은 https://kim-dragon.tistory.com/122 을 참조해주세요!

google에 github access token 발급만 검색하셔도 많은 포스팅을 확인하실 수 있습니다 :)

이 토큰을 가지고 우리는 Repository의 [Settings] - [Security] - [Secrets] - [Actions] 에서 New repository secret을 클릭하여 Secret을 등록해주세요

 

Workflow 작성하기

Repository의 Actions 탭에서 set up a workflow yourself를 눌러 yml 파일을 작성해주세요

yml의 각 부분에 대한 설명은 주석을 참고해주세요
단 해당 코드를 활용해여 workflow 설정 시 주석을 삭제하고 설정하시는 것을 권장드립니다.

name: CI/CD Docker

# 트리거를 수행할 브랜치를 지정합니다. push 혹은 merge 될 때 실행되도록 설정할 수 있습니다.
on:
  push:
    branches: [ master ] 

# Docker image의 이름과 version, name을 환경변수로 지정합니다.
env:
  DOCKER_IMAGE: ghcr.io/${{ github.actor }}/trading
  VERSION: ${{ github.sha }}
  NAME: go_cicd

# workflow는 다양한 jobs로 구성되는데 이러한 jobs 중 build와 deploy를 생성해줍니다.
# 이 때 steps 하위의 name은 각 단계에서 무엇을 실행할지를 작성해줍니다. 
# runs-on은 어떤 OS에서 실행될지를 지정해줍니다.
jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      # 1단계: 현재 상태의 소스코드를 cotainer 안으로 checkout 해주는 역할을 합니다.
      - name: Check out source code
        uses: actions/checkout@v2
      # 2단계: continer 안에 docker가 실행될 수 있는 환경을 설치하는 역할을 합니다.
      - name: Set up docker buildx
        id: buildx
        uses: docker/setup-buildx-action@v1
      - name: Cache docker layers
        uses: actions/cache@v2
        with:
          path: /tmp/.buildx-cache
          key: ${{ runner.os }}-buildx-${{ env.VERSION }} # runner 설정에서 읽어들일거에요.
          restore-keys: |
            ${{ runner.os }}-buildx-
      # 3단계: github token을 이용해 GHCR에 로그인하는 역할을 합니다.
      - name: Login to ghcr
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GHCR_TOKEN }}
       # 4단계: GHCR로 Docker image를 만들고 push 합니다.
      - name: Build and push
        id: docker_build
        uses: docker/build-push-action@v2
        with:
          builder: ${{ steps.buildx.outputs.name }}
          push: true
          tags: ${{ env.DOCKER_IMAGE }}:latest

# GHCR에 로그인 후 저장된 Docker Image를 이용해 컨테이너를 실행시킵니다.
# Docker run 단계는 실행 중인 도커 컨테이너를 중지하고 이전 버전의 컨테이너와 이미지를 삭제 후 새로운 이미지로 컨테이너를 run 합니다.
  deploy:
    needs: build
    name: Deploy
    # self-hosted는 필수 값입니다. 
    # 뒷 부분에 작성되는 이름은 Runner(EC2) 지정 시 사용할 이름입니다.
    runs-on: [ self-hosted, label-go ]
    steps:
      - name: Login to ghcr
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GHCR_TOKEN }}
      - name: Docker run
        run: |
          docker stop ${{ env.NAME }} && docker rm ${{ env.NAME }} && docker rmi ${{ env.DOCKER_IMAGE }}:latest
          docker run -d --name go_cicd --restart always ${{ env.DOCKER_IMAGE }}:latest

Runner 설정하기

이제 runner를 설정해주면 마무리가 됩니다.
Repository의 [Settings] - [Actions] - [Runners] 로 가서 New self-hosted runner를 클릭해주세요.

우리가 사용할 EC2에 맞는 OS와 architecture를 선택해주세요.


그럼 아래와 같이 download, configure이 생성됩니다.

이 항목을을 한 라인씩 복사해서 EC2에서 실행해주세요.
최종적으로 ./config.sh를 실행하면 다음과 같이 4단계에 걸쳐 입력을 요청하게 됩니다.

Enter the name of the runner group to add this runner to : 엔터
Enter the name of runner : 엔터
Enter any additional label : label-go (워크플로우 yml에 작성했던 라벨명
Enter name of work folder : 엔터

최종적으로 ./run.sh는 백그라운드로 실행해주세요.

nohup ./run.sh &

# EC2의 빌드 로그를 확인할 수 있습니다. 
tail -f nohup.out

여기까지 실행하면 다음과 같은 결과를 확인할 수 있습니다.

세팅이 완료되면 runnurs에 등록이 되었을 것입니다. 이제 설정한 branch에 push 하면 자동으로 빌드와 배포가 적용됩니다. 빌드와 배포 로그는 [Repository] - [Actions] 탭에 추가된 workflow에서 확인할 수 있습니다.