2026-04-20 임대 Apple Silicon 클라우드 Mac에서의 Ruby Bundler와 CocoaPods 결정적 CI
SSH로 Mac mini M4 또는 Mac Studio 빌더를 임대해 iOS CI를 돌리는 팀은 여전히 많은 CocoaPods 코드베이스를 운용합니다. 실패 모드는 “Pods가 나쁘다”가 아니라 비결정적 Ruby 툴체인입니다. 한 잡은 시스템 pod을 쓰고, 다른 잡은 화요일에 올라간 Homebrew를 타며, 또 다른 잡은 gem install cocoapods가 ~/.gem에 남긴 상태를 씁니다. 이 2026-04-20 런북은 임대 Apple Silicon 호스트에서 Bundler로 관리되는 CocoaPods를 HK / JP / KR / SG / US 전역에 표준화하고, 캐시 디렉터리를 잡별 워크스페이스에 맞추며, 멀티테넌트 머신의 NVMe 사용을 예측 가능하게 합니다. SwiftPM 대 CocoaPods, CLT 대 전체 Xcode, 병렬 xcodebuild 레인을 함께 읽어 의존성 해석과 컴파일 단계의 전제를 맞추세요.
헤드리스 빌더에서 Bundler가 여전히 중요한 이유
CocoaPods는 Ruby 프로그램입니다. 호출하는 pod 실행 파일의 안정성은 뒤의 gem 집합에 달려 있습니다. Bundler는 Gemfile.lock으로 그 집합을 고정하며, 열두 개 제품 팀이 하나의 클라우드 Mac 플릿을 공유할 때 필수입니다. Bundler 없이 “내 브랜치는 녹색”은 종종 “마지막으로 로그인한 사람이 전역 CocoaPods를 올렸다”는 뜻입니다.
- 재현성 — 동일한
Gemfile.lock으로 리전 간 해석 동작이 같아집니다. - 감사 가능성 — 보안이 릴리스 간 gem 버전 차이를 비교할 수 있습니다.
- 격리 —
bundle install --path vendor/bundle로 gem을 공유 홈이 아닌 워크스페이스에 둡니다.
Ruby 툴체인 매트릭스(3.1 대 3.2 대 3.3)
Apple Silicon macOS 이미지는 최근 시스템 Ruby를 포함하는 경우가 많고, 일부 팀은 rbenv나 asdf를 추가합니다. 플릿마다 하나의 정책을 골라 인프라 저장소에 인코딩하세요. 빌드 메타데이터에 정확한 ruby -v를 xcodebuild -version 옆에 기록합니다.
| 접근 | 장점 | 위험 |
|---|---|---|
| 시스템 Ruby + Bundler | 신규 SSH 호스트에서 빠른 부트스트랩 | OS 업그레이드가 Ruby를 올릴 수 있음; plist나 CI 환경으로 고정 |
| 사용자별 rbenv | 패치 레벨까지 정확 | launchd 잡은 rbenv shim을 명시적으로 소스해야 함 |
| asdf와 .tool-versions | Ruby와 Node 등을 한 파일로 | 첫 실행 설치 시간이 더 김 |
Gemfile과 잠금 파일 규율
Gemfile과 Gemfile.lock을 모두 커밋합니다. cocoapods는 검증된 마이너로 고정하고, 플러그인(예: cocoapods-acknowledgements)을 명시합니다. CI에서는 다음을 선호합니다.
bundle config set --local deployment 'true'
bundle config set --local path 'vendor/bundle'
bundle install --jobs 4 --retry 3
pod install 전에 bundle check를 실행해 Gemfile을 바꾼 뒤 Gemfile.lock을 갱신하지 않은 경우 빠르게 실패시키세요.
bundle exec pod install(및 --deployment 추가 시점)
항상 bundle exec pod install을 사용합니다(Bundler가 잠금 파일을 엄격히 적용하게 하려면 bundle exec pod install --deployment). 금요일 밤의 비결정성을 즐기지 않는 한 프로덕션 파이프라인에서 맨 pod을 호출하지 마세요. CI 캐시에는 결정적인 CP_HOME_DIR을 넘기거나, 잡 디렉터리 아래로 범위를 한정한 공식 캐시 환경 변수를 씁니다.
~/Library/Caches/CocoaPods에 쓰면 부분 다운로드가 생길 수 있습니다. $CI_JOB_ID나 저장소 클론 경로별로 캐시를 분리하세요.
캐시, Pods/, 워크스페이스 배치
Pods/와 *.xcworkspace 생성은 해당 빌드의 클론 경로 안에 둡니다. 에페메럴 워크스페이스에서는 체크섬이 Gemfile.lock + Podfile.lock과 일치할 때만 실행 간에 vendor/bundle과 CocoaPods specs 캐시를 유지하고, 어긋나면 공격적으로 무효화합니다. 오래된 specs 캐시는 네트워크 문제처럼 보이는 모호한 해석 오류를 만듭니다.
NVMe와 멀티테넌트 위생
CocoaPods 다운로드는 설치당 수백 MB를 더할 수 있고, 여러 Podfile을 가진 모노레포는 비용이 배가됩니다. 512 GB 공유 호스트에서는 시뮬레이터와 아카이브 정리의 디스크 가이드를 함께 적용하세요. pod 단계 중 디스크가 루틴하게 70%를 넘으면 레인을 나누거나 요금을 통해 1 TB / 2 TB 노드로 옮기고, 파이프라인 중간의 끝없는 가지치기에 의존하지 마세요.
지역 빌더: CDN과 지연
싱가포르나 도쿄에서 specs CDN 접근은 보통 훌륭하지만, 기업 프록시나 TLS 검사가 재시도를 늘립니다. bundle install 재시도 플래그를 넣고, 보안팀이 미러나 캐싱 프록시를 요구하면 리전별 예외를 문서화해 HK와 미 동부가 일관되게 동작하게 하세요.
관련 런북
SwiftPM으로 레인을 이전한다면 SwiftPM 해석과 캐시로 캐시 크기와 잠금 의미를 비교하세요. Pods 해결 이후 서명은 기존 자동/수동 서명 가이드를 다시 확인하세요. Bundler는 프로비저닝 프로필을 대체하지 않습니다.
FAQ: 클라우드 Mac의 Bundler + CocoaPods
| 질문 | 실무 답변 |
|---|---|
| Homebrew CocoaPods는? | CI에서는 피하고 Bundler 관리 gem을 써서 업그레이드를 코드 리뷰로, 우연한 패키지 범프로 만들지 마세요. |
| Bundler 2 대 1은? | 메이저를 표준화하세요. 개발 노트북과 CI 불일치는 흔한 “로컬에선 된다” 원인입니다. |
| CI가 Pods/를 커밋해야 하나요? | 팀 정책입니다. 완전 밀봉 빌드를 위해 모두 커밋하거나 매번 새로 생성하세요. 반쯤 커밋은 금지입니다. |
한 줄 요약: CocoaPods를 다른 컴파일러 툴체인처럼 다루세요. 버전을 고정하고, 캐시를 범위 지정하고, 공유 SSH 빌더에서는 항상 bundle exec를 경유하세요.