API 서버 자동으로 배포하기 CI/CD - 플리맨 프로젝트

김철기·2023년 1월 26일
5

플리맨(FleaMan)

목록 보기
11/14
post-thumbnail

해당 포스팅은 플리맨(FleaMan) 프로젝트의 광고 겸 개발일지입니다.
시간되실때 플리맨(https://fleaman.shop) 서비스 한번 사용해주시고 피드백주시면 감사하겠습니다.

바쁜 사람들

요즘 사람들 정말 바쁘다. 그리고 나도 정말 바쁘다. 그래서 자동화할 수 있는 작업은 최대한 자동화해야했다. 예전 포스팅에서 CloudFlare Pages를 사용해 프론트엔드를 자동배포하는 것에 대해서 다뤘었다. (참고: 공짜인데 파워풀한 Cloudflare와 Nginx를 써보자 - 플리맨 프로젝트)
오늘은 플리맨 API 서버 배포를 어떻게 자동화했는지에 대해서 다뤄보려고 한다.

자동 배포, CI/CD?

포스팅을 진행하기 전에 CI/CD라는 단어 자체를 처음 들어봤을 분들을 위해 짧게 설명하겠다. CI/CD는 Continuous Integration/Continuous Delivery의 약자로 한국말로 지속적 통합 + 지속적 배포다. 쉽게 말해 우리가 작성한 코드를 통합하고 배포하는 자동화된 파이프라인을 의미한다.
너무 자세히 들어가면 재미없으니 좀 더 자세한 내용이 필요한 분은 다음 링크를 참고하길 바란다.
(참고: https://www.redhat.com/ko/topics/devops/what-is-ci-cd)
결과적으로 이번 포스팅에서는 CI/CD를 어떻게 하는지에 대해서 알아볼 것이다.

공짜가 좋아

플리맨은 아직까지 제대로된 수익이 없기때문에(광고수익은 아직 정산조건에도 못미친다..) 최대한 공짜를 사용했다. 바로 Github! 아마 대부분 애용하고 있을 것이다. 플리맨은 Github에서 공짜로 제공하는 Action 기능을 이용해 CI/CD를 구축했고 사용하고 있다.

어떻게 사용할까?

일단 기본적으로 Action의 기능을 사용하려면 .github/workflows 폴더가 존재해야하고, 트리거가 발생했을때 어떻게 동작해야하는지에 대한 설명이 적혀있는 yaml 파일이 폴더 내부에 있어야 한다.
.github/workflows/app_test.yaml 같은 path 구성이다.

app_test.yaml

위에서 자세히 설명하진 않았지만 CI/CD 중 CI 과정은 Test + Merge 라고 생각하면 편하다. 그중에 Merge는 Git으로 수행할 것이고 Merge전에 Merge해도 되는지 Test하는 부분을 우리는 작성해야 한다.
on 아래에 있는 부분은 jobs가 동작할 조건이다. 아래처럼 작성하면 master 브랜치에서 pull_request가 발생했을 때 jobs가 동작하게 된다.
아래 jobs는 ubuntu + python3.7 환경에서 pytest 명령어를 수행하게 된다. pytest까지 설명하면 너무 길어지니 pytest에 대한 설명은 생략하도록 하겠다.

on:
  pull_request:
    branches:
      - master

jobs:
  apptest:
    name: App Test
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set up Python 3.7
        uses: actions/setup-python@v1
        with:
          python-version: 3.7
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt
      - name: Test
        run: |
          pytest -v

우리가 작성한 코드를 PR하면 리뷰와 Merge전에 정상적으로 API가 동작하는지 테스트해볼 수 있는 것이다.

deploy.yaml

CI가 완료되었으면 이어서 CD도 해줘야된다. CD 작업은 AWS Elastic Beanstalk 또는 쿠버네티스를 사용해 배포하는 방법이 있고, 플리맨처럼 규모가 작은 서비스는 ssh로 서버에 접근해 단순 명령어로 배포할수도 있다.
해당 포스팅에서는 플리맨에서 사용한 ssh 방법을 설명하겠다. 다른 2가지 방법은 필자가 예전에 포스팅했던 것을 참고해볼 수 있겠다.

ssh action은 아주 심플하다. 일단 아래 코드에서 jobs는 master 브랜치에서 push가 발생하면 동작한다. 이어서 jobs에서는 서버의 정보인 host, username, key, port와 실행될 명령어 script를 받아 서버에서 명령어를 실행시킨다. ${{ secrets.HOST }}으로 표기된 부분은 보안을 위해 Github secret 변수를 사용한 것이다. secret 변수는 settings 탭의 secrets and variables - Actions에서 설정할 수 있다.

플리맨은 git으로 CI된 코드를 가져온 뒤 docker-compose를 이용해 docker를 빌드하고 새로 빌드된 이미지로 API 서버를 다시 올린다. script 부분은 만약 API 실행방법이 다르면 수정해서 사용하면 된다.

name: cd
on:
  push:
    branches:
      - master
jobs:
  cd-pipeline:
    name: continuos deploy
    runs-on: ubuntu-latest
    steps:
      - name: executing remote ssh commands using password
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.HOST }}
          username: user
          key: ${{ secrets.PRIVATE_KEY }}
          port: 22
          script: |
            cd 코드가 있는 경로
            git pull
            docker-compose build
            docker-compose down
            docker-compose up -d

이렇게 하면 큰 무리없이 CD를 마무리 지을 수 있을것이다.

마무리

오늘은 자동으로 API 서버를 배포하는 방법에 대해서 다뤄봤다. 아마 아직도 FTP 코드를 직업 업로드하거나 서버에 ssh로 수동으로 접근해 작업하는 분들이 분명 있을것이다. 만약 그렇다면 이번 포스팅을 참고해서 꼭 CI/CD 구축해보길 바란다. 아주아주 편하고 더 안전하다.
물론 위 방법대로 구축하면 문제가 되는 부분도 있다. 서버 1대에서 동작하다보니 새로운 서버로 배포되는 순간에 서비스가 되지 않는다. 이런 문제는 사실 서버 구조를 바꾸고 쿠버네티스 또는 Elastic Beanstalk를 사용해 롤링방식으로 해결할 수 있다. 혹시 궁금한 부분이 있다면 필자가 나름 관련 포스팅을 많이 했기 때문에 필자의 예전 포스팅을 한번 쭉 읽어보는 것도 좋을것 같다.
플리맨을 서비스한 이후로 방문자 통계에 예민해졌다. 백엔드 관련 포스팅은 프론트나 구글 애드같은 포스팅에 비해 방문자가 많이 적더라.. 😂
그래도 누군가에게 도움이 될만한 내용은 꾸준히 포스팅하겠다. 필자는 velog에서 플리맨으로 접근한 방문자 통계를 볼때 의리가 느껴져서 꽤나 감동받는다. (플리맨에 관심 주셔서 감사합니다!)

profile
Deepveloper, deeplol.gg, fleaman.shop

0개의 댓글