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이 동작한다.
🔚 마무리
이번 글에서는 프로젝트를 Self-hosted Runner를 통해 자동으로 빌드하고 VM에 배포하는 CI/CD 파이프라인을 구성하는 과정을 다뤄보았다.