카테고리 없음 / / 2025. 5. 19. 23:56

GitHub Actions 대신 Self-hosted Runner로 NestJS 프로젝트 CI/CD 구성하기

GitHub Actions 대신 Self-hosted Runner로 NestJS 프로젝트 CI/CD 구성하기

 

 

이전에 작업하던 프로젝트가 회사 내부 방화벽과 밀접하게 연관되어 있는 상태라 실제 작업이나 프로토타입 작업 등이 회사 내부 네트워크에서 작업이 되어야 해서 다른 곳에서 작업한 결과를 사내 내 PC VM에 자동으로 올리고 관리하려고 CI/CD 파이프라인을 만들었고 CI/CD 배포를 위한 방법으로 gitLab, gitHub, jenkins 등이 있지만 나는 개인적으로 주로 사용하는 GIthub을 사용했다.

 

 

2025.05.13 - [전체보기] - 방화벽 시스로그(Firewall Syslog) 수집기 #1 - 우분투 서버로 로그 수집(Feat. BlueMaxNGF)

 

방화벽 시스로그(Firewall Syslog) 수집기 #1 - 우분투 서버로 로그 수집(Feat. BlueMaxNGF)

방화벽 시스로그(Firewall Syslog) 수집기 #1 - 우분투 서버로 로그 수집(Feat. BlueMaxNGF) 아무리 단순한 어플리케이션을 만들었다고 해도 이 어플리케이션을 서버에 올려서 서비스를 하는 순간부터는

dbsyys.tistory.com

 

 

Github에는 GitHub Actions을 활용하면 자동화된 배포 파이프라인을 손쉽게 구축할 수 있는데 이 글에서는 가상 서버(VM)에 NestJS 프로젝트를 GitHub Actions으로 CI/CD 파이프라인을 만들어 자동화 하려고 했다. 하지만 Self-Hosted Runner 라는 GitHub이 지원하는 기능을 사용하게 되었다.

 

 

🤔 왜 Self-hosted Runner를 사용하게 되었나?

처음에는 GitHub Actions만으로 빌드 & 배포까지 모두 진행하려고 했다. 그러나 VM이 사설망 내에 위치하고 있고, 방화벽으로 인해 GitHub Actions에서 직접 접속이 어려운 환경이었다. (따로 port를 할당 받아 포트 포워딩 등을 하기가 애매한 상황)

 

 

문제 상황

  • GitHub Action의 SSH 배포 방식은 VM이 외부와 통신할 수 있어야 동작함
  • VM은 사설망 내에 존재하고, 방화벽을 통해서만 외부 접근 가능

 

 

선택지 비교

조건 GitHub-hosted Runner Self-hosted Runner
VM이 외부와 통신 가능한 경우 가능 가능
사설망 내부에 VM 존재 ❌ 어려움 ✅ 적합
네트워크 제약 있음 ❌ 어렵거나 추가 설정 필요 ✅ 내부 실행으로 문제 없음

결국 VM 내부에 Self-hosted Runner를 설치하는 방식으로 CI/CD를 구성.


🧱 폴더 구조 및 Workflow

project-root/
├── .github/
│   └── workflows/
│       └── ci-cd.yml

.github/workflows/ci-cd.yml 파일을 생성해 CI/CD를 정의합니다.

GitHub Actions 이나 Self-hosted Runner를 사용하기 위해선 해당 프로젝트의 메인 경로의 .github 폴더와 하위에 yml 파일이 있어야 한다. (메인 경로란 .git 이나 .gitignore 등의 파일이 있는 폴더)

 

 

🛠️ GitHub Actions Workflow

yaml
name: Build and Deploy on Self-Hosted Runner

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: self-hosted

    steps:
      - name: ✅ Checkout repository
        uses: actions/checkout@v3

      - name: ⚙️ Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: 22

      - name: 📦 Install dependencies
        run: npm install

      - name: 🛠️ Build project
        run: npm run build

      - name: 🚀 Restart PM2 process
        run: |
          pm2 restart log-collector || pm2 start dist/main.js --name log-collector

 

workflow 위치에 있는 ci-cd.yml 파일이다. 차례대로 어떤 브랜치에 push할 것인지, 어떤 작업을 순서대로 진행 할 것인지에 대해서 순차적으로 작성한다.

 

 

🏃Self-hosted Runner

Settings -> Actions -> Runners

 

해당 위치에서 New self-hosted runner를 클릭하고 차례대로 진행하면 된다. Runner를 만든게 하나도 없다면 OS 선택 부분부터 시작해서 차례대로 설치하는 화면이 나온다.

 

* Linux로 설치 시, root 계정으로 아래 이미지의 설치를 진행하면 안된다. 새로운 계정을 만들어서 수행하도록 하자 *

sudo adduser user1

 

 

🔐 GitHub Secrets 설정 (GitHub Action 사용 시)

GitHub Repository > Settings > Secrets and variables > Actions 에서 다음 항목들을 추가합니다:

이름 설명
SSH_PRIVATE_KEY Runner에 접속할 SSH 키 (optional)

Self-hosted Runner를 쓰는 경우엔 위의 설정을 optional 하게 사용한다.

GitHub Action의 경우는 ssh를 통해서 접근하고 빌드와 배포를 하게되므로 ssh key를 RSA 등으로 암호화 된 키도 필요하며, 서버 IP나 Port, 경로 등도 경우에 따라서 추가할 수 있다. Self-hosted Runner를 사용하게 되면 이 작업은 생략 가능하다.

 

 

정상 작동 확인

* CI/CD가 정상적으로 동작하기 전 환경 설정을 먼저 해주자.

📂 git pull
🛠️ npm install
🛠️ npm run build
🔁 pm2 restart app

# pm2 작동 확인
pm2 list
pm2 logs log-collector

 

pm2를 이용하여 서버를 띄운 후에 소스 변경 후 push를 하게되면 Action이 동작한다.

 

실패 케이스 (github action 사용 했을 때)
정상 동작

 

 

🔚 마무리

이번 글에서는 프로젝트를 Self-hosted Runner를 통해 자동으로 빌드하고 VM에 배포하는 CI/CD 파이프라인을 구성하는 과정을 다뤄보았다.

 

 

 

 

  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유