Self-hosted Runner와 Vercel 배포 비교: git push 뒤에서 무엇이 다른가

GitHub에 커밋을 푸시하면 자동으로 서비스가 배포됩니다. 겉으로 보면 GitHub Actions의 Self-hosted Runner와 Vercel은 똑같아 보입니다.

git add .
git commit -m "feat: 검색 기능 추가"
git push origin main

하지만 git push 이후의 책임과 실행 장소는 상당히 다릅니다. Self-hosted Runner에서는 내가 준비한 컴퓨터가 워크플로를 실행하고 서버까지 갱신합니다. Vercel에서는 Git 연동을 감지한 Vercel이 관리형 환경에서 빌드하고 새 배포를 만든 뒤 운영 도메인을 연결합니다.

이 글에서는 두 방식의 배포 흐름, 설정 위치, 환경변수, 데이터베이스 변경, 롤백과 선택 기준을 하나씩 비교합니다. CI가 생소하다면 먼저 git push 후 자동 검사가 시작되는 이유: Continuous Integration(CI) 입문을 읽어도 좋습니다.

먼저 한 문장으로 구분하기

Self-hosted Runner: GitHub가 작업을 지시하지만 작업을 실행하는 컴퓨터와 배포 대상은 내가 관리합니다.

Vercel Git 배포: Git 이벤트를 Vercel이 직접 받아 빌드·배포·프리뷰 URL·운영 도메인 반영을 관리합니다.

GitHub 공식 문서에서 Self-hosted Runner는 사용자가 배포하고 관리하는 시스템으로 정의됩니다. 하드웨어와 운영체제, 설치 도구를 자유롭게 선택할 수 있지만 운영체제·소프트웨어 업데이트와 장비 비용도 사용자의 책임입니다. 자세한 특성은 GitHub Self-hosted Runner 안내에서 확인할 수 있습니다.

반면 Vercel은 연결된 Git 저장소의 브랜치 푸시마다 자동 배포를 만들고, Production Branch의 변경은 운영 배포로, 다른 브랜치는 Preview 배포로 처리합니다. Vercel Git 배포 문서에 이 기본 동작이 설명되어 있습니다.

전체 흐름 비교

Self-hosted Runner 방식

git push
↓
GitHub Actions가 workflow 감지
↓
온라인 상태의 Self-hosted Runner에 작업 전달
↓
저장소 checkout
↓
의존성 설치 → 검사 → 테스트 → 빌드
↓
Docker 이미지 교체 또는 서버 프로세스 재시작
↓
내 서버의 기존 도메인에서 새 버전 제공

GitHub는 runs-on의 라벨과 일치하는 온라인 Runner를 찾아 작업을 보냅니다. Runner가 꺼져 있거나 조건에 맞는 장비가 없으면 작업은 대기합니다. 실제 명령 실행, Docker 데몬, 내부 네트워크와 디스크는 모두 내 장비에 있습니다.

Vercel Git 연동 방식

git push
↓
Vercel Git Integration이 변경 감지
↓
Vercel이 저장소와 환경 설정을 불러옴
↓
의존성 설치 → 프레임워크 빌드
↓
새 배포 생성
↓
일반 브랜치: Preview URL
Production Branch: 운영 도메인 반영

개발자가 별도 Runner 서비스를 켜 두거나 Docker Compose로 컨테이너를 교체하지 않아도 됩니다. Vercel 대시보드에서 저장소, Root Directory, 프레임워크, Build Command, 환경변수와 Production Branch를 한 번 설정하면 이후 커밋이 자동 배포의 입력이 됩니다.

항목별 차이

비교 항목 | Self-hosted Runner | Vercel Git 배포
작업 실행 위치 | 내가 관리하는 물리·가상·클라우드 장비 | Vercel 관리형 빌드 환경
시작 조건 | GitHub Actions YAML의 on 설정 | 연결된 저장소의 브랜치 push·PR
실행 대상 선택 | runs-on 라벨·Runner 그룹 | Vercel 프로젝트와 연결된 저장소
빌드 명령 | 워크플로에 모든 명령을 직접 작성 | 프레임워크 자동 감지 또는 Build Command 설정
서버 반영 | Docker, SSH, systemd 등을 직접 구성 | Vercel이 새 배포 생성과 도메인 연결 처리
Preview | 별도로 환경과 도메인을 만들어야 함 | 일반 브랜치·PR마다 기본 제공
환경변수 | GitHub Secrets, Runner 파일, 서버 설정 | Development·Preview·Production 환경별 설정
데이터베이스 | 내부망 접근과 마이그레이션 순서를 직접 제어 | 외부 접근 가능한 DB와 별도 마이그레이션 전략 필요
롤백 | 이전 이미지 태그·백업·Compose 설정으로 직접 복구 | 이전 배포를 다시 Production으로 연결 가능
런타임 자유도 | OS·Docker·GPU·로컬 도구까지 자유롭게 선택 | Vercel이 지원하는 런타임과 배포 모델 안에서 사용
운영 책임 | Runner, OS, 저장공간, 네트워크, 인증서 등을 관리 | 빌드·배포 인프라 상당 부분을 Vercel이 관리

Self-hosted Runner 배포는 어떻게 구성할까

다음은 Runner가 설치된 Linux 서버에서 직접 검사하고 Docker Compose를 갱신하는 단순한 예입니다.

name: Deploy

on:
push:
branches: [main]

jobs:
deploy:
runs-on: [self-hosted, linux, x64]

steps:
- uses: actions/checkout@v6

- name: Install dependencies
run: npm ci

- name: Verify
run: |
npm run typecheck
npm run lint
npm test
npm run build

- name: Replace containers
run: docker compose up -d --build

runs-on: [self-hosted, linux, x64]는 세 라벨을 모두 가진 Runner에 작업을 전달합니다. 라벨과 그룹을 이용한 작업 배정은 Self-hosted Runner 워크플로 사용법에 정리되어 있습니다.

이 방식의 장점은 제어력입니다. Runner가 데이터베이스와 같은 내부망에 있을 수 있고, Docker 이미지, 네이티브 라이브러리, GPU, 대용량 디스크처럼 프로젝트에 필요한 환경을 마음대로 구성할 수 있습니다. 배포 순서도 “DB 스키마 적용 → 애플리케이션 교체 → 헬스체크 → 실패 시 이전 이미지 복구”처럼 세밀하게 작성할 수 있습니다.

대신 Runner 프로세스가 멈추거나 디스크가 가득 차고 Docker 캐시가 손상되면 내가 복구해야 합니다. 여러 작업이 같은 장비를 재사용하므로 이전 작업의 파일과 프로세스가 남지 않도록 정리하는 것도 중요합니다.

Vercel 배포는 어떻게 구성할까

Vercel의 기본 Git 연동에는 배포 YAML이 꼭 필요하지 않습니다.

Vercel에서 GitHub 저장소를 가져옵니다.

프로젝트의 Root Directory와 프레임워크를 확인합니다.

Development·Preview·Production 환경변수를 등록합니다.

Production Branch와 운영 도메인을 정합니다.

저장소에 커밋을 푸시합니다.

이후 일반 기능 브랜치에 푸시하면 고유한 Preview URL이 만들어지고, main 같은 Production Branch에 병합하거나 푸시하면 운영 배포가 생성됩니다.

feature/search push
→ Preview Deployment
→ https://프로젝트-브랜치-식별자.vercel.app

main merge
→ Production Deployment
→ 실제 서비스 도메인 반영

이 구조의 가장 큰 장점은 브랜치마다 별도 미리보기 환경을 직접 만들 필요가 없다는 것입니다. 기획자나 고객에게 Preview URL을 전달해 실제 화면을 확인한 뒤 병합할 수 있습니다. 같은 저장소를 기반으로 하더라도 Preview와 Production 환경변수를 구분할 수 있습니다.

다만 Vercel을 일반적인 Docker 호스트와 동일하게 보면 안 됩니다. 임의의 장기 실행 프로세스, 특정 OS 패키지에 의존하는 서비스, 내부망 전용 자원, GPU 작업처럼 서버 자체를 통제해야 하는 워크로드는 Self-hosted 환경이 더 자연스럽습니다.

CI와 배포가 동시에 시작되는 문제

GitHub Actions CI와 Vercel Git 연동을 모두 push에 연결하면 둘은 보통 각각 이벤트를 받고 실행됩니다.

main push
├─ GitHub Actions: 타입·린트·테스트
└─ Vercel: Production 빌드·배포

즉, 기존 Self-hosted 워크플로처럼 “테스트가 성공해야 다음 배포 단계가 시작된다”는 순서를 자동으로 보장하는 구조와는 다릅니다. 직접 main에 푸시하는 운영에서는 CI가 실패하기 전에 Vercel 빌드가 진행될 수 있습니다.

가장 단순한 해결책은 Pull Request와 보호 브랜치를 사용하는 것입니다.

기능 브랜치 push
├─ GitHub Actions CI
└─ Vercel Preview

CI 성공 + 리뷰 완료
↓
main 병합
↓
Vercel Production 배포

이렇게 하면 CI 실패 커밋은 main에 들어오지 못하고, Vercel의 Production 배포는 검증이 끝난 병합 커밋에서 시작됩니다.

기존 순차 워크플로를 그대로 유지하고 싶다면

배포 시작 시점을 GitHub Actions가 완전히 통제해야 한다면 Vercel Git 자동 배포 대신 Vercel CLI를 워크플로 안에서 사용할 수 있습니다.

GitHub Actions
1. 타입·린트·테스트
2. vercel build --prod
3. vercel deploy --prebuilt --prod

이 구성에서는 1단계가 실패하면 Vercel 배포 명령에 도달하지 않습니다. Self-hosted Runner나 GitHub-hosted Runner에서 빌드 결과를 만든 뒤 Vercel에 전달할 수 있습니다. Vercel은 이 방식을 GitHub Actions와 Vercel 연동 가이드로 안내합니다.

단, Git 자동 배포와 Actions 배포를 동시에 켜 두면 같은 커밋이 중복 배포될 수 있습니다. 어느 쪽이 배포의 주체인지 하나로 정해야 합니다.

데이터베이스 마이그레이션은 특히 구분해야 한다

애플리케이션 빌드와 데이터베이스 변경은 실패 영향이 다릅니다.

Self-hosted Runner에서는 내부 데이터베이스에 접근한 뒤 다음처럼 명확한 순서를 만들 수 있습니다.

백업 또는 변경 검토
→ 스키마 마이그레이션
→ 새 컨테이너 기동
→ 헬스체크
→ 실패 시 애플리케이션 롤백

Vercel에서는 여러 Preview 빌드가 동시에 생길 수 있으므로 모든 빌드가 공용 운영 DB에 마이그레이션을 실행하게 만들면 위험합니다. 스키마 변경은 Production 배포 경로의 별도 작업으로 제한하거나, 호환 가능한 변경을 먼저 적용한 뒤 애플리케이션을 배포하는 식으로 분리하는 것이 안전합니다.

특히 컬럼 삭제나 타입 변경처럼 되돌리기 어려운 작업은 “Vercel이 자동 배포하니까 빌드 명령에 넣는다”로 끝내면 안 됩니다. DB 마이그레이션의 실행 주체와 한 번만 실행되는 조건을 별도로 정해야 합니다.

환경변수와 비밀값의 위치

Self-hosted 방식에서는 보통 세 위치를 구분합니다.

GitHub Actions에서만 필요한 값: GitHub Secrets

Runner 실행에 필요한 값: Runner 서비스 환경 또는 안전한 비밀 관리 도구

운영 애플리케이션 값: 서버의 환경 파일이나 비밀 저장소

Vercel에서는 프로젝트 설정에서 환경별 변수를 관리합니다.

Development: 로컬 개발에 내려받아 사용하는 값

Preview: 기능 브랜치와 Pull Request 배포용 값

Production: 실제 운영 배포용 값

어느 방식이든 비밀값을 워크플로 YAML이나 저장소에 직접 적지 않는 원칙은 같습니다. Preview가 운영 DB나 운영 API 키를 사용하지 않도록 환경을 분리하는 것도 중요합니다.

롤백 방식도 다르다

Self-hosted 서버에서는 이전 Docker 이미지 태그와 환경 설정을 보관해 두고 컨테이너를 다시 띄우는 방식이 일반적입니다. 애플리케이션은 되돌릴 수 있어도 이미 변경된 데이터베이스는 별도로 복구해야 하므로 백업과 호환성 전략이 필요합니다.

Vercel은 커밋마다 별도 배포를 만들기 때문에 이전에 정상 동작하던 배포를 다시 Production에 연결할 수 있습니다. Git 커밋을 되돌려 새 배포를 만들거나 기존 배포를 승격하는 식입니다. 이 역시 데이터베이스까지 자동으로 과거 상태로 돌리는 것은 아니므로 애플리케이션 롤백과 데이터 롤백은 구분해야 합니다.

어떤 상황에 무엇이 더 적합할까

Vercel이 편한 경우

Next.js와 웹 프론트엔드를 빠르게 배포하고 싶을 때

기능 브랜치마다 Preview URL이 필요할 때

서버·Docker·인증서 운영 부담을 줄이고 싶을 때

작은 팀이 코드와 제품 기능에 집중하고 싶을 때

Git 기반의 단순한 운영 배포 흐름이 잘 맞을 때

Self-hosted Runner가 편한 경우

사내망의 데이터베이스나 장비에 접근해야 할 때

Docker Compose나 특정 Linux 패키지를 그대로 사용해야 할 때

GPU, 대용량 디스크, 특수 하드웨어가 필요할 때

장기 실행 작업과 여러 백엔드 프로세스를 한 환경에서 운영할 때

배포 순서, 네트워크, 비용과 저장 위치를 직접 통제해야 할 때

혼합 구성이 좋은 경우

GitHub Actions에서 테스트하고 Vercel에서 웹을 배포할 때

프론트엔드는 Vercel, API·DB·AI 작업은 Self-hosted 서버에 둘 때

Vercel Preview를 활용하면서 운영 배포 승인과 DB 변경은 Actions에서 통제할 때

사내 시스템은 Self-hosted로 유지하고 외부 공개 사이트만 Vercel을 사용할 때

둘 중 하나를 완전히 버릴 필요는 없습니다. 서비스의 각 부분이 요구하는 실행 시간, 네트워크 위치, 데이터 민감도와 운영 부담에 따라 역할을 나누는 편이 현실적입니다.

선택 전에 확인할 질문

이 서비스는 일반적인 웹 요청·응답 모델에 맞는가?

내부망, GPU, 로컬 파일, 특정 Docker 환경이 필요한가?

브랜치별 Preview가 얼마나 중요한가?

데이터베이스 마이그레이션은 누가 언제 실행할 것인가?

CI 실패 전에 Production 배포가 시작돼도 괜찮은가?

운영체제와 Runner 장애를 직접 관리할 시간과 역량이 있는가?

문제가 생겼을 때 애플리케이션과 데이터를 각각 어떻게 되돌릴 것인가?

앞의 질문에서 인프라 제어 요구가 높으면 Self-hosted 쪽에 가깝습니다. 반대로 웹 배포 속도와 Preview 협업, 운영 부담 감소가 중요하면 Vercel이 편합니다.

마무리

Self-hosted Runner와 Vercel은 모두 git push를 자동화의 시작점으로 사용할 수 있습니다. 차이는 push 자체가 아니라 그다음에 누가 실행 환경을 소유하고 어디까지 책임지는가에 있습니다.

Self-hosted Runner는 내가 만든 자동화 공장입니다. 원하는 장비와 도구, 내부망을 사용할 수 있지만 공장이 멈추면 직접 고쳐야 합니다. Vercel은 웹 배포에 맞춰 준비된 관리형 공장입니다. 저장소를 연결하면 Preview와 Production 배포를 빠르게 얻지만 플랫폼의 실행 모델 안에서 설계해야 합니다.

처음 Vercel을 접한다면 “self-hosted runner가 사라졌다”기보다 “웹 빌드와 배포를 실행하던 runner·서버·도메인 전환을 Vercel에 위임했다”고 이해하면 가장 자연스럽습니다.