먼저 알아야 할 핵심
- 문제는 xcodebuild 하나가 아니라 캐시 수명과 실행 환경 수명 불일치입니다.
- GitHub-hosted는 매 실행 초기화, 셀프호스팅 Runner는 워밍 상태 유지가 가능합니다.
- DerivedData와 CocoaPods 캐시를 지속화하면 대기 시간을 크게 줄일 수 있습니다.
- 디스크 압박과 서명 준비 오버헤드는 컴파일 지연으로 오해되기 쉽습니다.
- Flutter 팀은 Mac 임대로 48시간 계측 후 월 단위 셀프호스팅 Runner를 결정하는 방식이 안전합니다.
로컬 Mac vs GitHub Actions: 추가 시간은 어디서 생기나
로컬에서 벤치마크할 때 대부분 팀은 이런 전제로 비교합니다.
- 로컬: 지속 SSD + 워밍 캐시 / CI: 일회성 VM + 콜드 의존성.
- 로컬: 동일 사용자 서명 상태 / CI: 매 실행 keychain 부트스트랩.
- 로컬: 같은 호스트 반복 빌드 / CI: 브랜치별 캐시 미스 증가.
반면 CI 파이프라인에서는 보통 다음과 같이 동작합니다.
- 매 실행마다 깨끗한 워크스페이스에 checkout
flutter build ipa또는xcodebuild archive를 Release로 실행- 호스티드 Runner는 캐시가 잘 남지 않아 매번 콜드 스타트
팀이 `xcodebuild archive`만 비교하면 실제 원인을 놓칩니다. checkout, pod install, keychain 생성, DerivedData 무효화가 누적되어 체감 2~3배로 보입니다.
xcodebuild가 CI에서 느려지는 5가지 원인
GitHub Actions 환경과 셀프호스팅 Runner 전환 단계 모두에서 반복되는 패턴입니다.
- 1) 무상태 Runner가 의존성 레이어를 매번 리셋 GitHub-hosted VM은 job마다 초기화되어 SPM, Pods, 모듈 캐시가 안정적으로 워밍되지 않습니다. actions/cache만으로는 변동을 모두 흡수하기 어렵습니다.
- 2) DerivedData 경로 변동으로 증분 빌드 실패 임시 경로를 쓰면 로컬에서 재사용되던 결과물이 CI에서 무효화되어 재컴파일이 크게 늘어납니다.
- 3) Flutter 플러그인 변경이 Pods 해석을 콜드화 플러그인 업데이트는 Pod 해석 비용을 키웁니다. lockfile 관리와 deployment 모드가 없으면 `pod install` 시간이 불안정해집니다.
- 4) 서명/Keychain 단계의 직렬 오버헤드 인증서 import, keychain 생성/잠금해제는 CI에서 매번 수행됩니다. 로컬은 이미 준비된 상태라 차이가 커집니다.
- 5) 디스크 및 inode 압박이 빌드 쓰루풋 저하 CPU만 보면 오진하기 쉽습니다. 남은 SSD 용량과 inode 여유가 부족하면 인덱싱/쓰기 성능이 급격히 떨어집니다.
단계별 시간 로그 표 (Flutter iOS 예시)
플랫폼 교체 전에 먼저 이 형식으로 10회 이상 계측해 원인을 숫자로 확인하세요.
| 단계 | 로컬 Mac | GitHub Actions | 주요 원인 |
|---|---|---|---|
| flutter pub get | 0m25s | 1m10s | pub 캐시 워밍 부족 |
| pod install | 1m30s | 4m45s | Specs + plugin pod 콜드 해석 |
| xcodebuild compile/archive | 6m40s | 12m20s | DerivedData 재사용 실패 |
| codesign/export | 0m55s | 2m00s | 매 실행 keychain 초기화 |
| 총합 | 9m30s | 20m15s | 약 2.1배 |
xcodebuild 탓하기 전에
xcodebuild 전에 pod install을 놓치지 않았는지 확인하세요. CI에서 CocoaPods가 느려지는 대표 원인은 세 가지입니다.
Podfile.lock미커밋 — 의존성 해석이 매번 불안정ios/Pods캐시 없음 — job 종료 후 삭제- 불필요한
pod repo update— lockfile이 있으면 보통 불필요
CI에서는 pod install --deployment을 쓰고 Pods를 동일 SSD 경로에 유지하세요. 셀프호스팅 Mac mini는 GitHub 캐시 업로드/다운로드 대기를 줄입니다.
DerivedData, Pods, 캐시의 실전 설계
Flutter iOS에서는 DerivedData 절대 경로 고정과 Pods 캐시 안정화가 가장 큰 개선을 만듭니다. 셀프호스팅 Runner를 쓰면 CI를 일회성 환경이 아닌 지속 최적화 가능한 시스템으로 바꿀 수 있습니다.
GitHub-hosted를 유지해도 경로/lockfile을 결정적으로 관리하면 개선됩니다. 전환 가능하다면 셀프호스팅 Runner가 로컬과 유사한 워밍 경로를 제공합니다.
- target별 고정 derivedDataPath 사용.
- `pod install --deployment`로 lockfile 드리프트 차단.
- 디스크 여유와 inode를 CI 핵심 지표로 상시 관찰.
수정 패턴: 경로 고정 + 의존성 복원 결정성
아래 스니펫은 과한 트릭보다 운영 안정성을 우선한 베이스라인입니다.
- workflow에
concurrency추가 — 같은 브랜치의 오래된 빌드 취소 - 테스트는 Linux에서 — Mac 시간을
flutter test에 쓰지 않기 - Pods + DerivedData 영속화 — 셀프호스팅은 고정 경로, 호스티드는 세분화된 cache key
- 배포 flavor만 빌드 — 6개 flavor 스캔은 피하기
- Xcode / Flutter 버전 고정 — CI 내부
upgrade금지
# .github/workflows/ios-ci.yml
jobs:
ios:
runs-on: [self-hosted, macOS, ARM64, flutter-ios]
steps:
- uses: actions/checkout@v4
- name: Restore caches
run: |
mkdir -p "$HOME/Library/Caches/CocoaPods"
mkdir -p "$HOME/.pub-cache"
- name: Build with stable DerivedData path
run: |
flutter pub get
cd ios
xcodebuild -workspace Runner.xcworkspace -scheme Runner -configuration Release -destination 'generic/platform=iOS' -derivedDataPath "$HOME/ci-derived/runner" CODE_SIGNING_ALLOWED=NO
- name: Keep pod install deterministic
run: |
cd ios
pod install --deployment
이 기본만으로도 30~50% 개선되는 경우가 많고, 이후 Runner 풀 전략으로 추가 최적화할 수 있습니다.
속도 회귀 머지 전 체크리스트
Flutter/Xcode 업데이트 뒤 CI가 느려졌다면 반드시 실행하세요.
- ☐ CI는 Release/IPA, 로컬 비교는 Debug
- ☐ job에서
flutter clean또는 DerivedData 삭제 - ☐
pod install로그에 매번 대량 Installing - ☐ GitHub 호스티드 Runner 사용, 로컬 SSD 캐시 없음
- ☐ 16GB 머신에서 여러 job/시뮬레이터 동시 실행
- ☐ README만 바꿔도 iOS 전체 빌드 트리거
- ☐ CI Xcode 버전이 로컬과 불일치
앞 3개에 체크되면 캐시부터, 뒤 2개면 트리거 조건과 머신 스펙을 우선 점검하세요.
FAQ
GitHub Actions는 항상 로컬보다 느린가요?
항상은 아니지만 Flutter iOS에서는 캐시 워밍이 안 되면 자주 느립니다. 셀프호스팅 Runner가 격차를 줄여줍니다.
바로 셀프호스팅 Runner로 옮겨야 하나요?
먼저 계측이 우선입니다. 콜드 스타트 손실이 반복되면 한 workflow를 옮겨 10회 중앙값으로 비교하세요.
고가 하드웨어가 꼭 필요합니까?
대부분 아닙니다. 안정적 캐시가 가능한 Mac 임대 환경이면 충분히 개선됩니다.
팀 설득은 어떻게 하나요?
단계별 시간과 대기 비용, 그리고 릴리스 예측 가능성 개선을 함께 제시하면 합의가 빨라집니다.
클러스터 관련 링크
Flutter iOS CI를 재설계할 때 아래 순서를 권장합니다.
- 허브: Flutter iOS CI 아키텍처
- 캐시 심화: DerivedData / CocoaPods / SPM
- GitHub Actions용 셀프호스팅 Runner 구축
- iOS CI 서명/Keychain 안정화 가이드
- 장기 Runner 디스크와 inode 모니터링
실제 Apple Silicon에서 안정적인 iOS CI 속도를 원한다면
kvmboot cloud Mac은 Flutter iOS 워크로드에 맞춘 전용 호스트를 제공합니다. Mac 임대(일 단위)로 계측 후 셀프호스팅 Runner 월 운영으로 확장하세요.
CI 변동성 디버깅보다 배포 속도 회복에 집중하려면, cloud Mac 요금제 보기