[Part 2] 왜 Self-Hosted Runner를 선택했는가?

CI/CD를 구축하기 전에 여러 가지 방식을 검토했다.
이번 프로젝트에 필요한 요구사항은 다음과 같았다.
- 개발 서버 자동 배포
- 운영 서버 배포 자동화
- Docker Compose 기반 운영
- Health Check 기반 검증
- 자동 롤백
- 배포 전 백업
- Slack 알림
- 서비스별 독립 배포
단순히 코드를 빌드해 서버에 올리는 수준이 아니라 운영 자동화까지 고려해야 했기 때문에, 여러 CI/CD 방식을 비교해 보았다.
검토한 방식
1) GitHub Hosted Runner + SSH
가장 일반적으로 사용하는 방식이다.
GitHub Actions
↓
Hosted Runner
↓
SSH
↓
Linux ServerGitHub에서 제공하는 Runner가 빌드를 수행한 뒤, SSH로 배포 서버에 접속해 Docker를 재시작하는 구조다.
장점
- 구축이 간단하다.
- 별도의 Runner 서버가 필요 없다.
- GitHub에서 실행 환경을 관리해 준다.
하지만 프로젝트 요구사항을 고려하면 아쉬운 점이 있었다.
단점
- SSH Key 관리 필요
- 서버별 접근 권한 관리 필요
- 배포 스크립트 복잡도 증가
- 백업 및 복구 자동화 구현이 어려움
- Health Check 기반 롤백 구현이 복잡함
특히 배포 전 백업, Health Check 검증, 자동 롤백을 구현하려고 하니 SSH 원격 제어만으로는 관리 포인트가 너무 많아졌다.
2) Jenkins
대표적인 CI/CD 도구인 Jenkins도 검토했다.
GitHub
↓
Jenkins
↓
Build
↓
Deploy장점
- 강력한 플러그인 생태계
- 복잡한 파이프라인 지원
- 다양한 외부 시스템 연동
- 대규모 프로젝트 운영 사례가 풍부함
하지만 현재 프로젝트 규모에서는 다소 과한 선택이라고 판단했다.
단점
- Jenkins 서버를 별도로 구축해야 함
- 플러그인 관리 필요
- 유지보수 포인트 증가
- 백업 및 장애 대응 필요
- 러닝 커브 존재
프로젝트가 GitHub를 중심으로 개발되고 있었기 때문에, Jenkins를 추가로 운영하기보다 GitHub Actions를 적극 활용하는 편이 더 적합했다.
3) Self-Hosted Runner
최종적으로 선택한 구조는 다음과 같다.
GitHub
↓
Self-Hosted Runner
↓
Docker Compose
↓
개발 서버Self-Hosted Runner를 개발 서버 내부에 설치해, GitHub Actions가 서버 안에서 직접 실행되도록 구성했다.
Self-Hosted Runner를 선택한 이유
1. 서버 내부 자원을 직접 제어할 수 있다
Runner가 서버 내부에서 실행되기 때문에 Docker를 직접 제어할 수 있다.
docker compose pull
docker compose up -dSSH 접속 없이도 배포가 가능하고, Docker Compose 기반 운영 환경과도 잘 맞았다.
2. 배포 전 자동 백업이 가능하다
배포 전에 현재 상태를 자동으로 백업하도록 구성했다.
현재 이미지 백업
↓
현재 서비스 디렉토리 백업
↓
신규 버전 배포문제가 생기더라도 즉시 이전 상태로 복구할 수 있다.
3. Health Check 기반 자동 롤백
이번 프로젝트에서 가장 중요하게 생각한 기능이다.
배포 후 컨테이너가 떠 있다는 사실만으로 성공이라고 판단하지 않았다.
배포
↓
Health Check 검증
↓
성공 또는 자동 롤백Spring Boot Actuator의 Health Check로 실제 서비스 상태를 검증하고, 실패하면 이전 버전으로 자동 복구하도록 구성했다.
4. 서비스별 독립 배포
Admin, Web, Backend를 각각 별도의 Runner로 분리했다.
admin-runner
web-runner
backend-runner이를 통해 다음과 같은 효과를 얻었다.
- 서비스별 독립 배포
- 병렬 배포 가능
- 불필요한 대기 시간 감소
- 장애 발생 시 영향 범위 최소화
예를 들어 Admin 서비스를 배포하는 중에도 Backend 배포는 영향을 받지 않는다.
최종 선택
이번 프로젝트에는 Jenkins 수준의 복잡한 오케스트레이션이 필요하지 않았고, 단순 SSH 배포로는 자동 롤백과 백업 정책을 효율적으로 구현하기 어려웠다.
그래서 GitHub Actions와 Self-Hosted Runner를 조합해 다음 목표를 달성했다.
- Docker 기반 자동 배포
- Health Check 기반 검증
- 자동 롤백
- 배포 전 백업
- Slack 알림
- 서비스별 독립 배포
현재 프로젝트 규모와 운영 방식에서는 가장 단순하면서도 실용적인 선택이었다.