Github Actions와 AWS EC2로 CI/CD 구축 도전기(2)

승우·2025년 1월 20일
post-thumbnail

저번 시간에는 ec2 가상 머신에 nginx까지 올려보았다.

이제 본격적으로 yml 파일을 작성하여 CI 준비를 해보겠다.

우선, CI는 코드가 수정이 될 때마다 지속적으로 편하게 통합이 되어 빌드, 테스트를 하는 과정이라고 할 수 있다.

나는 main 브랜치에 새로 머지가 되면 CI/CD 파이프라인이 돌아 EC2에 서버가 배포될 수 있도록 할 계획이다.

1. EC2에 필요한 패키지 설치하기

우선 나는 express 프레임워크를 사용하여 개발하였기 때문에 ec2 인스턴스에 nodejs를 설치해주었다.

아래 명령어를 사용하여 nodejs를 설치하자.

curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs

2. Github Actions 환경변수 설정

그 다음으로 깃허브 액션에서 환경변수를 설정한다.

다들 알다시피 소스코드에 민감한 정보를 하드코딩하는 것은 보안상 매우 좋지 않으므로 ssh_key나 IP주소, DB URI 같은 것들은 전부 환경변수로 저장해 놓자!

위 사진처럼 New repository secret을 눌러 새로운 환경변수를 생성하면 되는데, 나는 EC2의 IP와 SSH의 private key를 환경변수로 지정했다.

private key를 저장할 때는 반드시

-----BEGIN RSA PRIVATE KEY-----
... 괴상한 문자열들
-----END RSA PRIVATE KEY-----

위와 같이 모든 내용을 전부 복사해야 한다.

문자열들만 해줬다가 에러로 흠씬 두들겨 맞음,,ㅜ

2. workflow 파일 만들기

Github Actions는 Github가 해당 저장소에서 .github 폴더를 찾고, 그 내부의 yaml 파일들을 읽어들여 인식하고 실행한다.

그러므로 프로젝트 루트 경로에 .github 폴더를 만들고 바로 하위 폴더에 workflows 폴더를 만든다.

workflows 폴더 안에는 main-deploy.yml이라는 파일을 하나 만들 것이다.

요런 구조,,

3. yml 파일 작성

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

name: deploy-main

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  deploy:
    runs-on: ubuntu-24.04
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Configure SSH
        run: |
          mkdir -p ~/.ssh
          echo "$EC2_SSH_KEY" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa

          cat >>~/.ssh/config <<END
          Host app_name
            HostName $EC2_IP
            User $EC2_USER
            IdentityFile ~/.ssh/id_rsa
            StrictHostKeyChecking no
          END
        env:
          EC2_USER: ubuntu
          EC2_IP: ${{ secrets.EC2_IP }}
          EC2_SSH_KEY: ${{ secrets.EC2_SSH_KEY }}

      - name: Copy Workspace
        run: |
          ssh app_name 'sudo mkdir -p /opt/app'
          ssh app_name 'sudo chown ubuntu:ubuntu /opt/app'
          scp -r ./[!.]* app_name:/opt/app

      - name: Install dependencies
        run: |
          ssh app_name 'npm install --prefix /opt/app/'

      - name: Install PM2 Globally
        run: |
          ssh app_name 'sudo npm install -g pm2'

      - name: Start Application with PM2
        run: |
          ssh app_name 'pm2 start /opt/app/app.js --name "my-app"'

      - name: Save PM2 Process List
        run: |
          ssh app_name 'pm2 save'

      - name: Check PM2 Process List
        run: |
          ssh app_name 'pm2 list'

위에서부터 천천히 읽어나가보자면,

우선 main 브랜치로 코드가 푸시되었을 때 워크플로우가 실행되도록 작성하였다.

내 ec2는 ubuntu-24.04 환경에서 실행되기 때문에 해당 내용을 jobs에 작성해주고, 아래 steps부터는 job 내에서 수행할 개별 작업들을 작성해주면 된다.

1. checkout

  • Github Actions가 실행될 때 기본적으로 저장소의 코드를 사용할 수 없기 때문에 코드를 가져오는 역할을 한다.

2. SSH 설정

  • ssh 키를 설정하여 EC2 서버에 접속할 수 있도록 설정한다.

  • chmod를 600으로 설정해야 권한 에러가 생기지 않으니 저 부분은 각별히 신경쓰도록 하자.

3. 애플리케이션 파일 전송

  • ec2 서버에 애플리케이션 파일을 복사하는 과정으로 /opt/app 디렉토리를 생성하고 ubuntu 사용자로 변경하여 로컬에 있는 파일을 ec2로 올리는 과정이라고 생각하면 된다.

4. 의존성 설치

  • 애플리케이션의 의존성을 설치하는 과정으로, --prefix 옵션으로 디렉토리를 지정하여 설치하도록 하자.

5. pm2 설치

  • pm2를 -g 옵션을 사용하여 전역에 설치하자.

  • 처음에는 pm2를 전역적으로 설치할 수 없다는 에러가 떠서,, 앞에 sudo를 붙여주니까 에러가 해결되었다..(매우 찜찜하지만,, 일단 돌아가니까;)

6. 확인하기

  • 이렇게 배포가 완료되면 반드시 IP:PORT로 접속해서 잘 돌아가는지 확인해보자!!

  • 예전에 해커톤에서 Github Actions는 잘 돌아갔으나 무슨 이유에서인지 배포가 잘 되지 않아 애를 먹었던 매우 슬픈 경험이 있기 때문에 반드시 잘 확인해보자..ㅜㅜ

이로써 험난했던 CI/CD 구축 도전기가 끝이 났다.

사실 지금도 main에 push를 할 때가 되면 행여나 예상치 못한 에러가 뜰까봐 심장이 뛰곤 하지만..

일반적으로 의존성 문제이거나 pm2의 PORT 충돌 에러긴 해서,, ec2 서버 상에서 npm run dev를 실행시켜서 직접 에러를 찾거나 pm2 logs로 에러 로그를 하나하나 뜯어보면 되기 때문에 점차 적응해나가는 것 같다.

확실히 직접 부딪쳐 보는 것이 두려움을 해소할 수 있는 가장 효과적인 방법이 아닐까 싶다.

profile
이것저것 해볼래요

0개의 댓글