깃허브 액션 무료 분을 다 쓰면 집 컴퓨터를 러너로 붙인다
비공개 저장소의 월 2,000분을 소진했을 때, 먼저 줄이는 방법과 자체 러너로 옮기는 절차를 정리합니다. 변수 하나로 되돌릴 수 있게 붙이는 구성까지 다룹니다.
무료 2,000분은 생각보다 빨리 닿는다
비공개 저장소에서 깃허브 액션을 쓰면 무료 플랜은 월 2,000분입니다. 처음에는 넉넉해 보입니다. 그런데 저장소가 늘고, 푸시할 때마다 도커 이미지를 굽고, 테스트가 붙기 시작하면 계산이 달라집니다.
차감 배율도 함정입니다.
| 러너 | 분당 차감 |
|---|---|
| 리눅스 | 1배 |
| 윈도우 | 2배 |
| macOS | 10배 |
macOS 러너에서 20분짜리 빌드를 열 번 돌리면 그것만으로 2,000분입니다. 저는 저장소가 다섯 개로 늘어난 시점에 한도에 닿았습니다.
한도에 닿으면 워크플로가 그냥 안 돕니다. 결제 수단을 등록하면 초과분이 과금되고, 등록하지 않으면 다음 달까지 기다려야 합니다.
1단계 · 먼저 줄인다
옮기기 전에 줄일 수 있는 게 꽤 됩니다. 이 세 가지만으로도 상당히 버팁니다.
문서만 고친 커밋은 빌드하지 않는다
README나 문서만 고쳤는데 도커 이미지를 다시 굽는 건 낭비입니다.
on:
push:
branches: [main]
paths-ignore:
- '**.md'
- 'docs/**'
- '.github/ISSUE_TEMPLATE/**'
주의할 점이 하나 있습니다. paths-ignore로 걸러진 커밋은 워크플로가 아예 실행되지 않으므로, 이 워크플로를 필수 상태 검사로 걸어 두었다면 병합이 영원히 대기 상태가 됩니다. 필수 검사로 쓰는 잡이라면 paths-ignore 대신 잡 안에서 조건 분기로 건너뛰게 하는 편이 안전합니다.
진행 중이던 앞 빌드는 취소한다
연달아 푸시하면 앞 빌드가 계속 돌면서 분을 먹습니다.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
main 브랜치 배포 워크플로에 이걸 걸 때는 한 번 더 생각해야 합니다. 배포 도중에 취소되면 중간 상태가 남을 수 있습니다. 저는 테스트·빌드 워크플로에만 걸고, 실제 배포 단계는 취소되지 않게 두었습니다.
캐시를 켠다
의존성 설치가 매번 처음부터 도는 건 가장 흔한 낭비입니다.
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
# 도커 빌드라면
- uses: docker/build-push-action@v6
with:
cache-from: type=gha
cache-to: type=gha,mode=max
2단계 · 그래도 모자라면 러너를 옮긴다
절감으로 안 되면 빌드를 도는 기계 자체를 바꿉니다. 깃허브가 빌려주는 컴퓨터 대신, 내가 가진 컴퓨터를 등록하는 방식입니다.
어디에 등록할지 먼저 정한다
| 범위 | 쓰는 경우 |
|---|---|
| 저장소 단위 | 한 저장소에서만 쓴다 |
| 조직 단위 | 저장소 여러 개가 공용으로 쓴다 |
저는 저장소 다섯 개가 같은 러너를 쓰기 때문에 조직 단위로 등록했습니다. 저장소마다 따로 등록하면 같은 기계에 러너 프로세스가 다섯 개 뜹니다.
설치
조직 설정의 Actions → Runners → New runner 화면에 그 기계에 맞는 명령이 그대로 나옵니다. 리눅스 x64 기준으로는 이런 모양입니다.
mkdir actions-runner && cd actions-runner
curl -o actions-runner-linux-x64.tar.gz -L \
https://github.com/actions/runner/releases/download/v2.x.x/actions-runner-linux-x64-2.x.x.tar.gz
tar xzf actions-runner-linux-x64.tar.gz
./config.sh --url https://github.com/<조직명> --token <등록토큰> --labels self-hosted,linux,x64
버전과 토큰은 화면에 나오는 값을 그대로 씁니다. 등록 토큰은 한 시간 뒤 만료됩니다.
서비스로 등록해서 재부팅에도 살아남게 한다
./run.sh로 띄우면 터미널을 닫는 순간 죽습니다. 서비스로 등록합니다.
sudo ./svc.sh install
sudo ./svc.sh start
sudo ./svc.sh status
macOS라면 svc.sh가 launchd 에이전트를 만들어 줍니다. 이때 로그인 세션 밖에서도 도구를 찾을 수 있는지 확인해야 합니다. 로그인 셸에서만 PATH가 채워지는 구성이라면 서비스로 뜬 러너는 docker: command not found를 뱉습니다. 이 함정은 별도 글에서 자세히 다뤘습니다.
아키텍처를 맞춘다
도커 이미지를 굽는다면 이 부분이 중요합니다. 깃허브 호스팅 러너는 x86_64입니다. 자체 러너가 Apple 실리콘(arm64)이면 같은 Dockerfile로도 다른 아키텍처 이미지가 나옵니다. 운영 서버가 x86_64라면 그 이미지는 안 돕니다.
선택지는 두 가지입니다. 아키텍처가 같은 기계를 러너로 쓰거나, docker buildx로 크로스 빌드하는 것입니다. 크로스 빌드는 QEMU 에뮬레이션이 붙어 느려지므로, 저는 아키텍처가 같은 기계를 골랐습니다.
3단계 · 되돌릴 수 있게 붙인다
여기가 실제로 값을 하는 부분입니다. 워크플로에 runs-on: self-hosted를 직접 박으면, 그 기계가 꺼졌을 때 모든 저장소의 빌드가 멈춥니다.
대신 어디서 돌릴지를 변수 하나로 뺍니다.
jobs:
build:
runs-on: ${{ vars.BUILD_RUNNER || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@v4
# ...
조직 변수(Settings → Secrets and variables → Actions → Variables)에 BUILD_RUNNER를 self-hosted로 넣어 두면 집 컴퓨터에서 돕니다. 그 값을 지우면 ubuntu-latest로 되돌아갑니다.
이 구성의 장점은 세 가지입니다.
- 코드를 안 고치고 왕복할 수 있다. 커밋도, 배포도 필요 없다
- 변수는 조직 단위라 저장소 다섯 개가 한 번에 움직인다
- 집 컴퓨터를 껐거나 급하게 빌드해야 할 때 변수만 지우면 된다
한 가지 주의할 점은, 자체 러너가 오프라인인 상태에서 BUILD_RUNNER가 켜져 있으면 잡이 실패하지 않고 큐에 대기한다는 것입니다. 러너가 다시 붙을 때까지 조용히 기다립니다. 기계를 꺼둘 거라면 변수도 같이 지우는 편이 낫습니다.
보안 · 공개 저장소에는 붙이지 않는다
자체 러너를 공개 저장소에 붙이면 안 됩니다. 공개 저장소는 누구나 풀 리퀘스트를 올릴 수 있고, 포크에서 올라온 워크플로가 자체 러너에서 실행될 수 있습니다. 남이 작성한 코드가 내 컴퓨터에서 도는 상태가 됩니다.
깃허브 공식 문서도 이 조합을 명시적으로 경고합니다. 저는 비공개 저장소에만 붙였고, 빌드 머신과 실제 서비스가 도는 서버도 분리했습니다. 빌드는 이미지를 만들어 레지스트리에 올리는 데까지만 하고, 운영 서버는 그 이미지를 받아 갑니다.
실제로 얼마나 버는가
깃허브에 내는 분당 요금은 0원이 됩니다. 대신 그 컴퓨터를 켜 두는 전기 요금이 듭니다. 이미 다른 용도로 24시간 켜 두는 기계가 있다면 추가 비용은 거의 없습니다.
빌드 시간은 기계 사양을 그대로 따라갑니다. 오래된 기계라면 깃허브 호스팅 러너보다 느릴 수 있습니다. 저는 배포가 급하지 않은 작업은 자체 러너에서 돌리고, 급할 때만 변수를 되돌리는 방식으로 씁니다.
정리
- 비공개 저장소 무료 분은 월 2,000분이고 macOS 러너는 10배로 깎인다
- 먼저 줄인다 · 문서 커밋 스킵, 중복 실행 취소, 캐시
- 그래도 모자라면 자체 러너를 조직 단위로 등록하고 서비스로 띄운다
- 아키텍처를 운영 환경과 맞춘다
- 어디서 돌릴지는 변수로 빼서 코드 수정 없이 왕복할 수 있게 한다
- 공개 저장소에는 붙이지 않는다
자주 묻는 질문
깃허브 액션 무료 분은 얼마나 주어지나요?
비공개 저장소 기준으로 무료 플랜은 월 2,000분입니다. 리눅스 러너가 1배, 윈도우가 2배, macOS가 10배로 차감되므로 macOS 러너를 쓰면 200분 만에 소진됩니다. 공개 저장소는 깃허브 호스팅 러너가 무료입니다.
자체 러너를 붙이면 정말 무료인가요?
깃허브에 내는 분당 요금은 없습니다. 대신 전기 요금과 그 컴퓨터를 켜 두는 비용이 듭니다. 이미 켜져 있는 기계가 집에 있다면 추가 비용은 사실상 전기 요금뿐입니다.
공개 저장소에도 자체 러너를 붙여도 되나요?
권장하지 않습니다. 공개 저장소는 누구나 풀 리퀘스트를 올릴 수 있고, 그 안의 워크플로가 자체 러너 위에서 실행될 수 있습니다. 남이 작성한 코드가 내 컴퓨터에서 도는 상황이 되므로 깃허브 공식 문서도 공개 저장소에는 쓰지 말 것을 명시하고 있습니다.
자체 러너로 옮기면 빌드가 느려지나요?
기계 사양에 따라 다릅니다. 오래된 데스크톱이라면 깃허브 호스팅 러너보다 느릴 수 있습니다. 그래서 어디서 돌릴지를 변수로 빼 두고, 급할 때는 다시 깃허브 쪽으로 돌리는 구성을 권합니다.