self-hosted 원격 Mac 러너에서 bundle install을 반복하는 팀을 위한 의사결정형 글입니다. rubygems.org·조직 미러·Git VCS가 동시에 열릴 때의 병목, BUNDLE_JOBS·BUNDLE_RETRY, vendor/cache·CI 캐시 키, Gemfile.lock --frozen 검수를 표와 체크리스트로 묶었습니다. 교차 참고: PHP·Composer, Gradle·Maven, Git·Docker 풀, 사전 풀·버전 일관성. 내비: ·기술 블로그(로그인 불필요).

시나리오와 병목: 국경 간 풀, Git gem, lock 일관성

bundle install은 인덱스 메타데이터·.gem 다운로드·Git 클론이 한 파이프라인으로 겹칩니다. 원격 Mac은 데이터센터 위치·회선·프록시가 로컬 개발기와 달라 동일 Gemfile이라도 CI만 느리거나 실패하는 경우가 흔합니다.

  • 병렬 폭주: BUNDLE_JOBS를 과도하게 올리면 NAT·방화벽·rubygems/GitHub 쪽 동시 연결 한도에 걸려 오히려 타임아웃이 늘 수 있습니다.
  • Git 소스 gem: github:·git: 의존은 깊은 히스토리·서브모듈·LFS까지 따라와 IO가 커집니다. 토큰 범위·URL 스킴(SSH vs HTTPS) 불일치 시 401/403만 반복됩니다.
  • lock 드리프트: 미러 전환·플랫폼 블록 추가·Bundler 메이저 업 후 Gemfile.lock 미갱신이면 --frozen 단계에서 즉시 실패하거나, 반대로 조용히 다른 revision이 깔리는 사고로 이어집니다.

로그에서 Fetching gem metadata 대기인지, 특정 Git 리비전에서 멈추는지 먼저 나눈 뒤 아래 표의 파라미터를 고릅니다.

병렬과 연결 풀 파라미터: BUNDLE_JOBS·BUNDLE_RETRY·재시도 상한

Apple Silicon 원격 Mac에서 코어는 넉넉해도 외부 네트워크가 병목인 경우가 많습니다. 아래는 실행 가능한 기본치입니다(팀 회선에 맞게 조정).

항목 권장 시작값 의사결정 기준
BUNDLE_JOBS 4 (M4 10코어 기준 4~6) p95가 안정이면 +2씩. 타임아웃·429 증가 시 -2.
BUNDLE_RETRY / bundle install --retry 3 네트워크 플레이크 대응. 401·403에는 효과 없음→토큰·URL부터 수정.
셸 백오프 (실패 시) 2s → 4s → 8s, 최대 3회 CI retry:와 중복 시 총 시도 횟수가 과다해지지 않게 설계.
BUNDLE_WITHOUT development:test (배포 잡) 풀 볼륨·보안 표면 감소. lock은 동일 저장소 기준으로 유지.
# CI 전 단계에서 병렬·재시도 고정 (예: GitHub Actions / 셸) export BUNDLE_JOBS=4 export BUNDLE_RETRY=3 export BUNDLE_PATH="$GITHUB_WORKSPACE/vendor/bundle" # 또는 bundle config set path 'vendor/bundle' bundle install --jobs 4 --retry 3 --path vendor/bundle # 네트워크 플레이크 시 (최대 3회, 2·4·8초) for i in 1 2 3; do bundle install --jobs 4 --retry 3 && break sleep $((2 ** i)) done

BUNDLE_AUTO_INSTALL처럼 암묵적 동작은 러너 이미지마다 달라질 수 있으므로, CI 스크립트에 명시적 bundle install을 두는 편이 재현성에 유리합니다.

국경 간 미러와 Git 소스 전략

rubygems.org 직접 풀이 느리거나 불안정하면 조직 승인 미러를 둡니다. Git 소스는 HTTPS + 토큰 또는 git config url.insteadOf로 자격 증명을 일원화하세요.

소스 유형 설정 수단 복붙 예시 (URL은 조직 정책으로 교체)
rubygems 미러 bundle config bundle config set mirror.https://rubygems.org https://<조직-미러>/rubygems/
GitHub HTTPS gem 호스트별 env export BUNDLE_GITHUB__COM=x-access-token:${GITHUB_TOKEN}
범용 Git 호스트 git config (글로벌/CI) git config --global url."https://oauth2:${TOKEN}@gitlab.example.com/".insteadOf "https://gitlab.example.com/"
사설 gem 서버 bundle config + Gemfile source bundle config set --local rubygems.pkg.github.com USERNAME:${TOKEN} (GitHub Packages Rubygems)
# 미러 + GitHub 토큰 (CI 시크릿에만 보관) bundle config set mirror.https://rubygems.org https://gems.example.com/rubygems/ export BUNDLE_GITHUB__COM="x-access-token:${GITHUB_TOKEN}" bundle install --jobs 4 --retry 3

미러와 원본을 섞으면 Gemfile.lockremote: 블록이 팀원마다 달라질 수 있습니다. 한 미러 정책을 정하고 lock을 저장소에 고정하세요.

lockfile 드리프트, vendor/cache, CI 캐시 키

bundle package --allvendor/cache.gem을 넣으면 CI는 외부 풀 없이 bundle install --local로 닫을 수 있습니다(저장소 용량·갱신 프로세스는 비용). 반면 캐시만 쓰는 경우에는 키 설계가 성패를 가릅니다.

전략 캐시/아티팩트 키 구성요소 비고
vendor/bundle Gemfile.lock 해시 + Ruby 버전 + Bundler 버전 플랫폼별 젬이 있으면 bundle lock --add-platform 반영 여부를 키에 포함.
vendor/cache Gemfile.lock + vendor/cache 디렉터리 지문 패키징 잡과 빌드 잡 키를 분리하면 무효화 범위를 줄일 수 있음.
미러 전환 기존 키에 미러 호스트 문자열 추가 오래된 메타·체크섬 불일치 방지용 의도적 캐시 미스.
Gemfile.lock 일관성 검수 체크리스트 (CI 게이트)
  • bundle install --frozen 또는 --deployment로 lock 위반 시 즉시 실패.
  • 머지 전 로컬/동형 Docker에서 동일 명령으로 lock 재생성 필요 시 PR에 lock diff 포함.
  • bundle check로 경로·플랫폼 누락을 스모크.
  • Bundler 메이저 업 시 Gemfile.lock 상단 BUNDLED WITH와 CI 이미지 버전 일치.
# lock 고정 설치 (CI 권장) bundle config set deployment 'true' bundle install --frozen --jobs 4 --retry 3 --path vendor/bundle # 오프라인 후보 (vendor/cache 채운 뒤) # bundle install --local --frozen --path vendor/bundle

FAQ

Q. SSH git@github.com: gem이 CI에서만 실패합니다.
A. 에이전트 포워딩 없는 러너에서는 HTTPS + 토큰이 단순합니다. BUNDLE_GITHUB__COM 또는 insteadOf로 팀 전체 URL 정책을 통일하세요.

Q. 캐시를 지웠는데도 특정 Git revision에서 멈춥니다.
A. shallow clone 한도·서브모듈·사내망 DNS를 확인하세요. 원격 Mac에서 git ls-remote로 동일 URL을 수동 재현하면 원인 분리가 빠릅니다.

Q. 실패 재시도를 몇 번까지 둘까요?
A. Bundler --retry 3 + 셸 백오프 3회를 넘기면 한도·비용만 커지는 경우가 많습니다. 근본 오류(인증·lock)는 재시도 전에 분류하세요.

정리: BUNDLE_JOBS·BUNDLE_RETRY·백오프 상한을 표로 고정하고, 미러·Git 토큰을 한 경로로 모은 뒤 vendor/cache 또는 캐시 키로 외부 변동을 흡수하면 원격 Mac Ruby CI의 재현성이 크게 좋아집니다. 동일 스펙의 전용 노드가 필요하면 로그인 없이 ·구매·요금·도움말(SSH)·고객 지원·기술 블로그에서 MacPull 원격 Mac으로 CI 러너를 맞추면 됩니다.

Ruby·Bundler CI

원격 Mac에서 bundle install을 안정적으로

MacPull 원격 Mac에 러너를 두고 미러·캐시·lock 정책을 동형으로 유지하세요. ·구매·도움말·고객 지원·기술 블로그는 로그인 없이 이용할 수 있습니다.

전용 Apple Silicon
SSH·CI 러너
유연한 기간
고객 지원