self-hosted

집에서 서비스를 오픈 해보자 (4) | CI/CD 연동하기

pepega 2024. 7. 18. 20:54

집에서 서비스를 오픈 해보자 (1) | 개요
집에서 서비스를 오픈 해보자 (2) | 서버 세팅하기
집에서 서비스를 오픈 해보자 (3) | dns 연결하기
집에서 서비스를 오픈 해보자 (4) | CI/CD 연동하기
 
이전 포스팅에서는
서비스를 오픈하여
User가 서비스에 접근하는 부분까지 구현을 완료했습니다.
 
이번 포스팅에서는
개발자가 Github에 코드를 push한 뒤
Github Actions을 활용하여 CI/CD를 진행하도록 하겠습니다.
 

 
이 사진에서 developer가 GitHub에 코드를 push 했을 때 일어나는 일들을 구현할겁니다.
코드를 push 하면 Raspberry Pi 안에 설치되어있는 Github Actions이
Container image를 기동합니다.
 

0. 사전 작업

이 글에서는
Raspberry Pi(ARM64)를 사용하고 있습니다.
 
만약 다른 컴퓨팅 자원을 사용한다면 cpu 아키텍처를 확인하고 오세요.
 
 

1. 서버에 Github Actions 설치하기

배포하기 원하는 Repository에 접속합니다.
 

Settings에 접속합니다.
 

미리 만들어 왔어요 ~~

좌측에 Actions에서 Runners에 접속한 뒤
New self-hosted runner를 클릭합니다.
 

 
여기서 자신의 OS 및 cpu 아키텍처에 맞춰 선택합니다.
이 글에서는 Raspberry Pi (ARM64)를 사용하기 때문에
Linux, ARM64를 선택하였습니다.
 

이제 GitHub에서 제공해준 가이드 대로
서버에 ssh 접속하여 command를 실행합니다.
 

 
이렇게 접속되면
GitHub와 서버가 연결이 완료된겁니다.
 

 
다시 GitHub repository에 접속하여
Setting -> Actions -> Runners에 접속하면
내 서버와 Github Actions가 연결된 것을 확인 할 수 있습니다.
 

2. GitHub Workflows 구성하기

2-1. 기본 구성하기

이제 CI/CD를 구성할 차례입니다.
이 글에서는 Rust 코드를 예시로 CI/CD하고 있습니다.
다른 언어가 필요할 경우 댓글 달아주시면
즉시 올리겠습니다 ㅋㅋ
 
언어가 달라도 대략적인 틀은 비슷합니다.
 

배포하기를 원하는 repository에 접속하여
Actions -> set up a workflow yourself을 클릭하거나
Suggested for this repository을 클릭해서 텍스트 편집기로 들어갑니다.
 
저는 Rust를 클릭했습니다.
 
 

요 코드를 하나씩 분리해보겠습니다.
 

name: Rust

on:
  push:
    branches: [ "master" ]  # master branch에 push 되었을 때 작동합니다.
  pull_request:
    branches: [ "master" ]  # master branch에 pull request 되었을 때 작동합니다.

 
branch에 변화가 일어났을 때 트리거됩니다.
master를 main 혹은 develop branch로 변경해도 됩니다.
 

env:
  CARGO_TERM_COLOR: always  # Rust의 환경변수를 설정해줍니다.

 
이 내용은 신경쓰지 않아도 됩니다.
 
 

jobs:
  build:

    runs-on: ubuntu-latest  # ubuntu 서버에서 작동합니다.

    steps:
    - uses: actions/checkout@v4  # repository 코드를 checkout 합니다.
    - name: Build
      run: cargo build --verbose  # 코드를 빌드합니다.
    - name: Run tests
      run: cargo test --verbose  # 테스트를 수행합니다.

 
ci를 실행합니다.
대략적인 내용은
branch에 변화가 일어났을 때
Github Actions에서 제공하는 ubuntu를 활용하여
코드를 빌드합니다.
 
빌드에 실패할 경우 아래 사진처럼 표시됩니다.

빌드에 실패한 코드는 의미가 없을 수 있으니
다시 확인해보거나 close 하면 됩니다 ㅋㅋ
 
 

2-2. 입맛대로 Github actions workflows 구성하기

Github Actions에서 제공해준 코드만 사용하면
그저 빌드만 하고 끝입니다.
우린 아직 빌드 후 배포를 진행하지 못했습니다.
 
우선 jobs의 build를 변경해줄겁니다.

jobs:
  build:
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
    runs-on: ${{ matrix.os }}

 
이렇게 되면
ubuntu에서만 빌드 되는 것이 아닌
ubuntu, macos, windows에서 동시에 빌드를 수행합니다.
시간은 오래 걸리겠지만
모든 os에서 테스트 하는게 의미 있는 것 같습니다.
 
 
이제 container 이미지를 build하고
dockerhub에 push하기 위한 ci/cd를 만들겁니다.
 
jobs 안에
아래 코드를 추가합니다.

  docker:
    needs: build
    runs-on: ubuntu-latest  # docker build는 ubuntu에서만 수행합니다.
    if: github.event_name == 'push'  # 코드가 push 되었을 때만 수행합니다.
    steps:
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3  # 가상머신을 만듭니다.
        
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3  # 멀티 플랫폼 이미지를 빌드하기 위해 필요한 Buildx를 설치합니다.
        
      - 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@v6  # 빌드된 이미지를 push 합니다.
        with:
          platforms: linux/arm64  # cpu 아키텍처를 선택합니다.
          push: true
          tags: gudrb963/klassic-quote-api:latest  # container image tag를 지정합니다. 
                                                   # 이 부분은 알맞게 변경해주세요.

 
이 코드에서 Docker Hub의 USERNAME과 PASSWORD가 필요합니다.
오픈소스에 개인 계정 정보를 입력 할 수는 없으니
github 에서 제공하는 secrets에 값을 할당하고
Github Actions에서 값을 불러오도록 할겁니다.
 

배포하기를 원하는 repository에 접속 한 뒤
Settings -> Secrets and variables -> Actions -> New repository secret 을 클릭합니다.
 
 

 
여기에 secrets의 값들을 넣어줍니다.
Name은 DOCKERHUB_USERNAME을 넣고
Secret은 실제 값을 넣습니다.
저는 계정명을 넣었습니다.

 
이 값들을 넣어주었습니다.
 
docker hub에 push까지 완료되었습니다.
 

  deploy:
    needs: [build, docker]  # build, docker push가 완료되어야 수행됩니다.
    runs-on: self-hosted  # 방금 내 서버에 설치한 github actions을 의미합니다.
    steps:
      - name: run deploy.sh
        run: |
          cd /applications/klassic-quote-api  # 해당 서버에서 command를 수행합니다.
          ./deploy.sh

 
deploy.sh는 아래와 같이 구성되어 있습니다.

docker compose pull
docker compose up -d

 
 
전체코드는 아래와 같습니다.

 
이제 코드를 master branch에 push 하면
build, docker push 후 deploy를 진행하고
 
master branch에 pull request 하면
build 까지만 진행하게 됩니다.

 
이제 cicd가 완성되었습니다.
 
이번 글에서는
developer가 github master branch에 pull request 한 경우 
build 및 테스트를 하도록 하였고
 
master branch에 push한 경우
build, test, deploy를 진행하도록 하였습니다.
 
다음 글에서는
번외로 모니터링을 할 수 있는 upptime을 추가해보겠습니다.