CI/CD 도입기

Lee Hyun Jun·2024년 12월 28일
0

이드 프로젝트 서비스가 출시되었고 본격적으로 홍보를 시작하기 전에, 분명 서비스가 시작되면 예상치 못한 버그들이 많이 발생할 것 같아서 반복된 작업을 줄이고자 CICD를 구축하려 했다.

가장 간단한 Github Actions을 이용했고, 내 예상과 다르게 너무 오래 걸렷다;;

그리고 실제 레포지토리에 Push 해보지 않으면 테스트해볼 수 없어서 commit이 엉망이 되었었는데 이것 때문에 git rebase에 대해 더 자세하게 알게되었다.

name: Dev CI-CD Pipeline

on:
  pull_request:
    branches:
      - release/dev
    types:
      - closed

on은 해당 workflows가 실행될 Event를 지정하는 것인데 GitHub Action 문서 여기 참조해보면 단순하게 push, merge, pull_request 말고도 많은 event가 있다.

내가 만든 Jobs에는 test, push, deploy가 있는데, 나는 release/dev 브랜치에 PR이 생성되면 test 작업이 실행되고 통과된 후 PR이 승인되어 merge된 후에 deploy 작업이 실행되게 만들고 싶었다.

처음에는 push와 pull_request 이벤트를 트리거로 설정했는데, workflows가 2번 실행되었다. 이유를 찾아보니 PR이 생성될 때 한 번 작동되고, 병합되는 과정에서는 push 이벤트로 감지되었다!
그래서 내가 원하는 의도대로 작동시키기 위해 types: closed를 추가하여 수정했다.

테스트 단계 (Test Job)

jobs:
  test:
    runs-on: ubuntu-latest
    if: github.event.pull_request.merged == false

    services:
      maindb:
        image: postgres:13
        env:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: ${{ secrets.DB_ROOT_PASSWORD }}
          POSTGRES_DB: ${{ secrets.TEST_DB }}
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
          
      redis:
        image: redis:6.2.6
        ports: 
          - 6379:6379

    steps:
      - name: checkout code
        uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.10'

      - name: Create .env file
        run: |
          echo "BISKIT_USER=${{ secrets.BISKIT_USER }}" >> .env
          ...환경 변수 설정...
          echo "DEBUG=True" >> .env

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements/requirements.txt

      - name: set python path
        run: |
          echo "PYTHONPATH=${{ github.workspace }}/apps" >> $GITHUB_ENV

      - name: Run test
        run: |
          pytest --rootdir=apps/

내가 설정한 첫번째 jobs인 test는 말 그대로 test code를 실행시키는 단계이다. actions/checkout@v4는 Github Action에서 지원하는 기능으로 현재 git의 최신상태 코드로 pull 한다.

내 프로젝트에서는 .env로 환경변수를 관리하고 있는데 Github Actions에서는 repository secrets를 이용해야 하고 ${{ secrets.SECRET_NAME }}의 형식으로 사용할 수 있다.

pytest를 실행시킬 때 경로 때문에 계속 에러가 났는데 --rootdir 옵션으로 해결했다. 이런 경로 문제가 예전에는 검색해도 찾기 힘들어서 항상 까다로웠는데, 역시 한 두번 겪고나니 뭐가 문제일지 감이 잡히더라

도커 이미지 빌드 및 푸시 (Push Job)

  push:
    runs-on: ubuntu-latest
    if: github.event.pull_request.merged == true
    steps:
      - name: Set DATE variable
        run: echo "DATE=$(date +'%Y%m%d-%H%M')" >> $GITHUB_ENV

      - name: checkout code
        uses: actions/checkout@v4

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          platforms: linux/amd64,linux/arm64
          push: true
          tags: ${{ secrets.DOCKERHUB_USERNAME }}/biskit:${{ env.DATE }}

이 단계는 test 성공 후 image 를 build & push하는 것이 목표이고, 여기에는 QEMU, Buildx가 포함되어 이미지가 여러 플랫폼에서 동작할 수 있도록한다.

platforms: linux/amd64,linux/arm64를 설정함으로써 Intel/AMD 프로세서(amd64)와 ARM 프로세서(arm64) 모두에서 실행 가능한 이미지를 생성한다.

  deploy:
    runs-on: ubuntu-latest
    if: github.event.pull_request.merged == true

    steps:
      - name: Remote ssh connect
        uses: appleboy/ssh-action@v0.1.9
        with:
          host: ${{ secrets.DEV_REMOTE_IP }}
          username: ${{ secrets.DEV_REMOTE_USER }}
          password: ${{ secrets.DEV_REMOTE_PASSWORD }}
          port: ${{ secrets.DEV_REMOTE_PORT }}
          script: |
            cd BISKIT-Backend
            git checkout ${{ secrets.DEV_BRANCH }}
            git pull origin ${{ secrets.DEV_BRANCH }}
            echo ${{ secrets.DOCKERHUB_TOKEN }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin
            docker pull ${{ secrets.DOCKERHUB_USERNAME }}/biskit
            docker compose -f docker-compose.local.yml up -d

마지막 단계는 PR 승인 후 closed 될 때 실행되는 deploy 단계로 서버에 접속해 docker image를 받고 container를 재실행시킨다.

push 단계에서 처럼 docker/login-action@v3을 했는데 불구하고, 계속 dockerhub가 안되길래 꽤 고생했다.

생각해보니 deploy 가 실행되고 있는 container에서가 아니라 배포 서버에 접속 한 후에 dockerhub에 로그인 해야하더라!

profile
My Secondary Brain

0개의 댓글

관련 채용 정보