brunch

You can make anything
by writing

C.S.Lewis

by 강수빈 Jan 25. 2024

Github actions로 맛보는 CI / CD

단 1시간만 투자해서 간단한 CI / CD를 진행해 보자!

Github actions만으로도 CI / CD를 할 수 있지 않을까?


Runner 생성


아래의 화면으로 이동하고 초록색 버튼인 New self-hosted runner를 선택한다.

Github repository > Settings > Actions > Runners

EC2의 운영체제가 Ubuntu이기에 Runner image의 2번째에 있는 Linux를 선택한다.

Linux 선택

Architecture는 그대로 사용하고 Download, Configure의 내용을 하나씩 복사해 EC2에서 실행한다.

Configure의 마지막에 있는 ./run.sh 명령어는 nohup ./run.sh & 로 실행한다.

./run.sh로 실행하면 해당 터미널에서 다른 작업을 할 수 없을뿐더러 터미널을 종료하면 run.sh도 종료된다. nohup ./run.sh &는 run.sh를 백그라운드에서 실행시키겠다는 의미이다.


환경변수 설정


.env를 github에 올릴 수는 없으니 환경변수를 따로 추가해 준다.

아래의 화면으로 이동해 초록색 버튼인 New repository secret을 눌러 환경변수를 추가할 수 있다.

한번 환경변수를 추가하면 그 내용을 다시 볼 수는 없고 수정과 삭제만 가능하다.

Github repository > Settings > Secrets and variables > Actions


Yaml 파일 작성


우선 CI를 위한 push.yml을 작성한다.

해당 repository의 바로 아래에 .github/workflows/push.yml 경로로 파일을 생성한다.

Yaml파일 작성 간에 띄어쓰기를 잘못하면 오류가 발생하니 주의해야 한다.

이제 yml 파일을 작성해 보자.


name: push

on:

  push:

    branches-ignore: [main, develop]

jobs:

  test:

    runs-on: ubuntu-22.04

    steps:

      - name: Checkout

        uses: actions/checkout@main

      - name: Setup Node

        uses: actions/setup-node@main

        with:

          node-version: '18'

      - name: Install npm packages

        run: npm ci

      - name: Test

        run: npm run test


name은 작업의 이름을 정의한다.

on은 어떤 순간에 해당 workflow가 실행되는지 설정할 수 있으며 내 경우에는 main branch와 develop branch 이외의 branch에 push 되는 순간 해당 workflow가 실행되도록 설정했다.

jobs에는 workflow의 작업 내용을 작성할 수 있다. 나는 push 간 test만을 진행할 것이기에 test라 이름 지었다.

runs-on은 해당 코드가 실행되는 환경으로 EC2의 운영체제를 적는다.

steps에는 실행하고자 하는 작업을 순서대로 적으면 된다.

uses는 github actions에서 만들어둔 steps를 가져다 쓰는 것으로 checkout은 내 repository의 최신 branch를 가져오고, setup-node는 node를 설치한다.

추가로 with를 사용해 node의 버전을 지정했다.

아후 npm ci로 package-lock.json의 파일을 설치하고 npm run test로 테스트를 진행했다.




다음은 CD를 위한 yml 파일을 작성한다.

마찬가지로 해당 repository의 바로 아래에 .github/workflows/deploy.yml 경로로 파일을 생성한다.


name: deploy

on:

  push:

    branches: [main]

env:

  SERVER_PORT: ${{ secrets.SERVER_PORT }}

  DB_AWS_HOSTNAME: ${{ secrets.DB_AWS_HOSTNAME }}

  DB_PORT: ${{ secrets.DB_PORT }}

  DB_USERNAME: ${{ secrets.DB_USERNAME }}

  DB_PASSWORD: ${{ secrets.DB_PASSWORD }}

  DB_DATABASE: ${{ secrets.DB_DATABASE }}

  JWT_SECRET: ${{ secrets.JWT_SECRET }}

  JWT_EXPIRE: ${{ secrets.JWT_EXPIRE }}

  HASH_SALT: ${{ secrets.HASH_SALT }}

  AWS_ACCESS_KEY: ${{ secrets.AWS_ACCESS_KEY }}

  AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

  AWS_REGION: ${{ secrets.AWS_REGION }}

  AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }}

jobs:

  deploy:

    runs-on: ['self-hosted', 'Linux', 'X64']

    steps:

      - name: Checkout

        uses: actions/checkout@main

      - name: Install npm packages

        run: npm ci

      - name: Build

        run: npm run build

      - name: Kill process

        run: fuser -k ${{ secrets.SERVER_PORT }}/tcp || true

      - name: Run background

        run: RUNNER_TRACKING_ID="" && nohup npm run start:prod &


중복되는 설명은 생략한다.

해당 workflow는 main branch에 push되는 순간에만 동작한다.

다른 branch에서 main에 merge하는 순간도 포함된다.


env에는 github에서 설정한 환경변수를 ${{ secret.ENVIRONMENT }} 형식으로 가져올 수 있다.

jobs를 deploy로 이름짓고 runs-on에 runner의 정보를 작성한다.

npm run build까지는 이전 설명과 동일하다.


fuser -k ${{ secrets.SERVER_PORT }}/tcp || true

이 명령어는 해당 포트를 사용 중인 프로세스가 있다면 해당 프로세스를 종료한다는 의미이다. 종료할 프로세스가 없어도 오류를 발생시키지 않고 다음 단계로 넘어간다.

RUNNER_TRACKING_ID="" && nohup npm run start:prod &

이 명령어는 runner가 종료되어도 해당 runner에 의해 실행된 프로세스를 살려두기 위해 작성되었다.

RUNNER_TRACKING_ID를 빈 문자열로 초기화하지 않으면 해당 서버를 백그라운드에서 실행하는 nohup npm run start:prod & 명령을 실행해도 runner가 종료됨과 함께 해당 프로세스도 종료된다.


마치며


이 방법이 올바른 방법인지는 모르겠지만 CI / CD를 할 수 있는 가장 간단한 방법임은 틀림없을 것이다.

앞으로 DevOps를 공부하다 보면 이 글의 방법이 부적절하다 생각하게 될 수도 있겠지만, 다른 복잡한 것은 사용하지 않고 github actions만으로 CI / CD를 하고 싶은 사람이 있다면 이 글이 도움이 되길 바란다.

keyword
작가의 이전글 Stacker-Labs, 개발자 커뮤니티
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari