Github Action CI/CD

sxxng_ju·2022년 9월 15일
3

CI/CD

지속적인 통합/지속적인 제공 또는 배포를 뜻하며, 개발 시간을 줄이고 릴리스 수를 늘리는 것을 목표로 하는 Agile 개발 방식에서 비롯되었습니다.
즉, 애플리케이션 개발 단계를 자동화하여 보다 짧은 주기로 고객에게 제공하는 방법입니다.

CI/CD 장점

코드의 검증에 들어가는 시간이 줄어들며 편의성이 증가하고 실수가 줄어듭니다.
테스트 코드를 반영하면 좋은 코드 퀄리티를 유지할 수도 있습니다.
일일이 작업하지 않기 때문에 개발에 더욱 신경 쓸 수 있습니다.

Github Actions

GitHub Actions는 GitHub에서 제공하는 CI/CD 도구입니다.

GitHub Actions를 사용하여 자동으로 코드 저장소에서 어떤 이벤트가 발생했을 때 특정 작업이 일어나게 하거나 주기적으로 어떤 작업들을 반복해서 실행시킬 수도 있습니다.(cron)

GitHub에서 소스 코드를 관리하고 있는 소프트웨어 프로젝트에서 사용할 수 있으며 다른 CI/CD 서비스 대비 진입장벽이 낮은 편입니다.

Github Actions 가격

public 저장소에서는 무료로 사용 가능하고 private 저장소에서는 한달에 500MB 스토리지와, 2000분의 실행시간 동안 무료로 사용할 수 있습니다.

Github Actions 구성

1. Workflow

GitHub Actions에서 가장 상위 개념인 워크플로우는 YAML으로 작성되고 Github Repository의 .github/workflows 폴더 아래에 저장합니다.

2. Event

Workflow 실행을 트리거하는 규칙이나 조건입니다. on 속성을 통해 조건을 정의할 수 있습니다. 예를들어 특정 브랜치로 push 하거나 특정 시간대마다 반복하거나 webhook을 사용해 외부 이벤트를 통해 실행될 수도 있습니다.

3. Job

Job은 독립된 가상머신이나 컨테이너에서 돌아가는 하나의 처리 단위로 기본적으로 병렬로 실행합니다.

4. Step

여러 단계를 순차적으로 실행하는 작업 순서입니다. 각 job은 여러 step으로 이루어져 있습니다. 커맨드나 스크립트를 실행할 때는 run 속성을 사용하고 액션을 사용할 때는 uses를 사용합니다. 여기서 Action은 빈번하게 필요한 반복을 재사용하기 쉽게 사용자들이 공유한 것입니다. 우리는 SSH를 사용하기 때문에 appleboy/ssh-action을 사용했습니다.

전체적인 배포순서(SSH)
1. 코드를 수정한다.
2. git add . git commit으로 소스를 관리한다.
3. git push로 github에 올린다. => Event
4. Github Actions에서 Event를 감지하여 Step을 실행한다.
5. SSH 원격지로 접속한다.
6. 작업 폴더로 이동한다.
7. git pull, yarn, yarn build, pm2 reload 실행을 통해 배포한다.

가상머신의 용량이 꽉차면서 위에 작성한 배포순서의 문제점을 발견했습니다. 위에 작성한 순서대로면 모든 과정이 서버에서 일어나게 되어 용량 차지를 하게됩니다. 이 방법을 해결하기 위해 우리는 github actions에서 제공하는 가상머신에서 모든 빌드를 마친 뒤 빌드파일 만을 우리의 서버로 전달해 서버에서는 우리의 빌드폴더만 관리하도록 할 것입니다.

전체적인 배포순서(SSH, SCP)

  1. git push 이벤트가 발생한다.
  2. 가상머신에서 우리가 작성한 코드를 내려받는다.
  3. Github actions의 가상머신에서 node modules를 설치한다.
  4. Build에 필요한 env 파일을 작성한다.(secret이용)
  5. 프로젝트를 빌드한다.
  6. SCP로 빌드한 파일을 우리의 서버로 보낸다.
  7. SSH 연결을 하여 우리의 서버로 접속하고 받은 빌드파일을 통해 reload를 해준다.

yml 파일 예제(SSH)

name: Node.js CI

on:
  push:
    branches: ["main"]

jobs:
  build:
    # 가상머신 버전
    runs-on: ubuntu-latest

    steps:
      # VM에 git code 받아오기 이 코드가 없으면 폴더에 코드가 하나도 안 들어옴
      - uses: actions/checkout@v3

      # Node modules 설치
      - name: install node modules
        run: yarn

      # build에 사용할 env 파일 생성
      - name: set env
        run: |
          echo "DATABASE_URL=$DATABASE_URL">>.env
          echo "NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL">>.env
          echo "JWT_SECRET_KEY=$JWT_SECRET_KEY">>.env
          echo "GMAIL_ADDRESS=$GMAIL_ADDRESS">>.env
          echo "GMAIL_PASSWORD=$GMAIL_PASSWORD">>.env
        env:
          DATABASE_URL: ${{ secrets.DATABASE_URL }}
          NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }}
          JWT_SECRET_KEY: ${{ secrets.JWT_SECRET_KEY }}
          GMAIL_ADDRESS: ${{ secrets.GMAIL_ADDRESS }}
          GMAIL_PASSWORD: ${{ secrets.GMAIL_PASSWORD }}

      # 프로젝트 빌드
      - name: build project
        run: yarn build

      # SCP로 빌드한 파일 보내기
      - name: SCP files via ssh key
        uses: appleboy/scp-action@master
        with:
          host: ${{ secrets.REMOTE_IP }}
          username: ${{ secrets.REMOTE_SSH_ID }}
          key: ${{ secrets.REMOTE_SSH_KEY }}
          port: ${{ secrets.REMOTE_SSH_PORT }}
          source: ".next/*, package.json, public/*, prisma/*, .env"
          target: "/home/${{ secrets.REMOTE_SSH_ID }}/partner-web-dev"

      # SSH 연결 후 pm2 reload
      - name: SSH pm2 start
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.REMOTE_IP }}
          username: ${{ secrets.REMOTE_SSH_ID }}
          key: ${{ secrets.REMOTE_SSH_KEY }}
          port: ${{ secrets.REMOTE_SSH_PORT }}
          script: |
            cd /home/${{ secrets.REMOTE_SSH_ID }}/partner-web-dev
            export NVM_DIR=~/.nvm
            source ~/.nvm/nvm.sh
            yarn
            npx prisma db push
            pm2 reload partner-web-dev

Trouble Shooting

  1. Not found Error
    script부분에 추가
script: |
	export NVM_DIR=~/.nvm
    source ~/.nvm/nvm.sh
  1. Key Error
    SSH 접속을 위해 public key를 원격지 서버의 ~/.ssh/authorized_keys에 저장하고 private key를 github secret에 저장

  2. secret 설정
    민감한 정보를 secret에 저장하기 위해서는 github 계정 권한이 Admin이어야 함

참고 사이트

  1. SSH 설정
  2. appleboy/ssh-action github
  3. 전체적인 GitHub Actions 개념

0개의 댓글