DevOps / CI·CD 2026년 5월 20일

2026-05-20 Xcode 16 프로비저닝 프로필 경로멀티레인 동시 Archive헤드리스로 임대한 Apple Silicon 클라우드 Mac에서(HK / JP / KR / SG / US

MacXCode Engineering Team 2026년 5월 20일 약 18분 읽기

홍콩, 도쿄, 서울, 싱가포르, 미국에서 Mac mini M4 빌더를 임대하고 Xcode 16을 헤드리스로 돌리는 팀은 조용한 호환성 변화에 부딪칩니다. 프로비저닝 프로필이 더 이상 레거시 MobileDevice 트리에만 “살지” 않습니다. Xcode 16은 표준 저장소로 UserData 아래를 읽고 쓰는 반면, 오래된 스크립트·Fastlane 헬퍼·서드파티 CLI는 여전히 .mobileprovision을 Xcode 이전 경로로 복사할 수 있습니다. 한 대의 임대 호스트에서 멀티레인 동시 xcodebuild archive를 더하면 그 경로 드리프트는 서명 경합, 유령 같은 “프로필을 찾을 수 없음” 오류, 개발자 노트북에서는 재현되지 않는 간헐적 errSecInternalComponent 실패로 이어집니다. 이 2026-05-20 런북은 정책을 앞에 둡니다. 호스트의 모든 도구가 Xcode 16 인식으로 갱신될 때까지 UserData와 레거시 위치 모두에 프로필을 미러링하고, 레인별 CI 키체인DerivedData 루트를 격리하며, 재고형 Mac mini M4에서는 측정한 NVMe·통합 메모리 여유가 없다면 동시 Archive 레인을 두 개로 제한합니다. 경로 비교 표, 멀티레인 매트릭스, 헤드리스 서명 트리아지, 8단계 롤아웃, FAQ를 제공하며 내용은 키체인 + 프로비저닝 CI 기준선, 자동 vs 수동 서명 가이드, 병렬 xcodebuild 운영 글과 맞춥니다.

헤드리스 임대 Mac에서 프로비저닝 경로 드리프트에 걸리는 사람

장애는 “디렉터리가 틀렸다”고 거의 알리지 않습니다. 레인 B의 Archive는 성공하는데 레인 A는 동일한 UUID를 가져왔음에도 No profile for team 'XXXXXXXXXX' matching를 뱉는 식입니다. 임대 호스트에서는 파급이 큽니다. 골든 이미지에 2024년 헬퍼 스크립트가 박혀 있고, Jenkins 플러그인은 여전히 ~/Library/MobileDevice/Provisioning Profiles만 호출하며, 신입의 Fastlane 레인은 UserData로 내려받는데 야간 cron은 레거시 폴더만 갱신합니다. 하나의 macOS 사용자 계정을 공유하는 멀티브랜치 CI는 경로를 의도적으로 분할하지 않는 한 모든 레인이 같은 홈을 읽어 드리프트를 키웁니다.

  • 릴리스 엔지니어가 Mac mini M4 한 대에서 서로 다른 번들 ID로 두 개 이상의 Archive를 동시에 돌릴 때는 레인마다 결정적인 프로필 해석이 필요합니다.
  • 플랫폼 팀이 골든 이미지를 유지할 때는 Xcode 16, xcodebuild, 보조 도구가 archiveexportArchive 중 어떤 경로를 읽는지 문서화해야 합니다.
  • 보안 검토자는 레인 A가 레인 B의 배포 인증서를 읽을 수 없다는 증거를 원합니다. 프로필을 핫스왑할 때 레인별 키체인은 협상 여지가 없습니다.

모든 설계 리뷰는 MacXCode 홈의 약속—Apple API에 가까운 Apple Silicon—에서 시작한 뒤, 임대 호스트의 체크아웃 옆에 어떤 서명 산출물을 두어야 하는지 매핑하세요. 여전히 MobileDevice에만 프로필을 복사한다면 신뢰할 수 있는 멀티레인 처리량을 막는 기술 부채로 다루어야 합니다. UserData 전환 이전에 쓰인 원격 Archive 가이드는 이번 업데이트와 함께 읽어야 합니다.

레거시 MobileDevice와 Xcode 16 UserData 프로필 경로

Xcode 16은 Xcode의 계정 창에서 프로필을 내려받거나 xcodebuild -allowProvisioningUpdates가 권한을 갱신할 때 디스크의 기본 저장소로 ~/Library/Developer/Xcode/UserData/Provisioning Profiles를 봅니다. 레거시 위치 ~/Library/MobileDevice/Provisioning Profiles는 많은 CI 레시피, 구형 Fastlane 액션, 내부 셸 설치기가 여전히 그쪽만 겨냥하기 때문에 의미가 남아 있습니다. 모든 진입점을 감사하기 전까지 안전한 운영 기본값은 프로필 교체 후마다 Apple이 plist에 넣은 UUID 파일명(security cms -D -i file.mobileprovisionUUID 키)으로 두 트리에 바이트 동일 사본을 두는 것입니다.

경로 주요 소비자 Xcode 16 동작 임대 CI 메모
~/Library/Developer/Xcode/UserData/Provisioning Profiles Xcode IDE, 최신 xcodebuild GUI 다운로드에 대한 표준 읽기/쓰기 복사 전 xcode-select 고정, Xcode 계정(Accounts)보내기로 검증
~/Library/MobileDevice/Provisioning Profiles 레거시 스크립트, 일부 Fastlane 버전 많은 CLI 흐름에서 여전히 인정 스크립트를 폐기할 때까지 여기에도 미러
레인 범위 스테이징(예: /var/ci/lane-a/profiles) 복사 전 사용자 정의 설치기 직접 읽지 않음, 홈 디렉터리 경합 완화 레인 작업마다 두 표준 경로로 복사
ASC API + -allowProvisioningUpdates 자동 서명 파이프라인 UserData만 채울 수 있음 API 키 봉인, Fastlane vs 네이티브 ASC 참고
수치 가드레일: 배포용 프로필을 교체할 때 7~14일 유효기간이 겹치게 유지하세요. 교체 도중 시작한 레인은 진행 중인 Archive가 모두 끝날 때까지 이전 UUID를 삭제하면 안 됩니다. 최신 프로필 세 개의 mtime을 security find-identity -v -p codesigning 옆에 기록하는 방법은 키체인 기준선에 있습니다.

Mac mini M4 한 대에서 멀티레인 동시 Archive 매트릭스

동시 Archive는 임대 Mac mini M4에서 “공짜 병렬”이 아닙니다. 통합 메모리, NVMe 큐 깊이, 서명 세션 상태는 부하 아래에서 여전히 직렬화됩니다. 아래 매트릭스는 각 레인이 전용 -derivedDataPath, 전용 CI 키체인, 미러링된 프로필을 쓴다고 가정합니다. 패턴은 병렬 작업 가이드스킴 + xcconfig 멀티브랜치 글과 같습니다.

레인 수 전형적 NVMe 여유 통합 메모리 운영 결론
직렬 Archive 1개 시스템 볼륨에 120 GB 이상 여유 최소 16 GB, 여유롭게 24 GB 공유 릴리스 트레인 기본값, 로그가 가장 단순
동시 Archive 2개 /var/ci 아래 레인당 120~180 GB 여유 24 GB 이상 권장 재고 M4에서 실무 상한, DerivedData + 키체인 격리
동시 Archive 3개 이상 2 TB급 NVMe, 공격적 정리 32 GB 이상이 아니면 압축 정체 기대 측정 후에만, 디스크 위생 일정 잡기
Archive + 무거운 테스트 샤드 루트 분리, ModuleCache 공유 금지 XCTest에 4 GB 여유 확보 테스트 후 Archive를 직렬로 하거나 호스트 분리

레인 범위 Archive 호출 예(명시적 지정자로 수동 서명):

KEYCHAIN_PATH=/var/ci/lane-a/ci.keychain-db DERIVED=/var/ci/lane-a/dd xcodebuild -workspace App.xcworkspace -scheme Release -configuration Release -archivePath /var/ci/lane-a/out/App.xcarchive -derivedDataPath "$DERIVED" CODE_SIGN_STYLE=Manual PROVISIONING_PROFILE_SPECIFIER='MyApp AppStore' archive

프로필이 “설치된 것처럼” 보일 때의 헤드리스 서명 트리아지

SSH 세션은 대화형처럼 느껴지지만 launchd와 CI 러너는 그렇지 않습니다. Xcode 16 업그레이드 뒤 흔한 헤드리스 실패는 다음입니다. MobileDevice에만 프로필을 복사했거나, 배포 신원을 로그인 키체인에 넣었는데 xcodebuild는 빈 CI 키체인을 가리키거나, 레인 B가 레인 A가 독점해야 할 키체인을 잠금 해제하는 경우입니다. 모든 Archive를 세 부분 지문으로 다루세요. security list-keychains, security find-identity -v -p codesigning, 두 프로필 디렉터리에서 최신 UUID 세 개만 ls -lt로 확인합니다.

codesignerrSecInternalComponent를 출력하면 Archive 전에 CI 키체인을 비대화로 잠금 해제하고, codesign 접근용 파티션 목록을 설정하며, 포털 수정 후 푸시·앱 그룹·연관 도메인처럼 프로비저닝 권한이 타깃 역량과 맞는지 확인하세요. ASC API 자동 서명은 익스포트까지 경로 드리프트를 가릴 수 있고, 수동 레인은 즉시 드러냅니다. 한 호스트에서 스타일을 섞기 전에 자동 vs 수동 서명을 읽으세요.

절대 공유 임대에서 두 레인을 같은 로그인 키체인에 두지 마세요. /var/ci 아래에 ci-lane-a.keychain-dbci-lane-b.keychain-db를 만들고 security import -k "$KEYCHAIN_PATH" -P "$P12_PASS" -T /usr/bin/codesign로 배포 .p12를 가져오며, 작업 기간마다 security list-keychains -s 범위를 정합니다.
증상 가능한 원인 다음 명령 또는 조치
Xcode 리포트에 프로필 누락 UserData가 비었고 레거시만 설치 UUID 파일을 UserData에 미러한 뒤 Archive 재실행
errSecInternalComponent 잠긴 키체인 또는 잘못된 파티션 목록 security unlock-keychain -p "$PASS" "$KEYCHAIN_PATH", set-key-partition-list
같은 커밋에서 레인 A는 통과, 레인 B는 실패 공유 DerivedData 또는 프로필 경합 -derivedDataPath 분리, 프로필 복사 직렬화
익스포트는 성공, 업로드는 거절 잘못된 프로필 유형 또는 만료된 권한 Export + ASC 업로드 체크리스트로 검증

Archive 후 레인 폴더를 지우기 전에 dSYM을 업로드하세요. dSYM 심볼리케이션 가이드/var/ci/…/out 아래에 레인별로 Archive가 남아 있다고 가정합니다.

Xcode 16 경로 + 멀티레인 Archive를 위한 8단계 롤아웃

  1. xcode-select -p를 대상 Xcode 16.app으로 고정하고 골든 이미지 매니페스트에 xcodebuild -version을 기록합니다.
  2. .mobileprovision을 복사하는 모든 스크립트를 감사하고, UUID 파일명으로 UserData와 MobileDevice 경로 모두에 쓰도록 설치기를 갱신합니다.
  3. 레인별 CI 키체인을 만들고 배포 인증서를 가져오며, 레인이 서로의 키체인 파일에 접근하지 못하게 합니다.
  4. CI 환경 블록에 KEYCHAIN_PATH, PROVISIONING_PROFILE_SPECIFIER(또는 프로필 UUID), 레인 범위 DERIVED_DATA_ROOT를 보냅니다.
  5. 레인마다 건식 xcodebuild -showBuildSettings를 실행하고 CODE_SIGN_STYLE서명 모드 가이드 정책과 일치하는지 확인합니다.
  6. -allowProvisioningUpdates는 ASC API 자격 증명이 봉인·모니터링될 때만 켭니다. 네이티브 ASC vs Fastlane을 참고하세요.
  7. 프로필 미러링이 안정될 때까지 Archive 레인은 하나로 시작하고, 별도 NVMe 루트와 로그 파일로 레인 둘을 추가합니다.
  8. 주간 디스크 정리를 예약하고 겹침을 두고 프로필을 교체하며, 레인 스테이징 디렉터리에 핫스왑 사본을 둡니다.

비대화 프로필 설치 패턴(레인 스테이징 경로는 교체):

UUID=$(security cms -D -i "$PROFILE" | plutil -extract UUID raw -) && cp "$PROFILE" "$HOME/Library/Developer/Xcode/UserData/Provisioning Profiles/$UUID.mobileprovision" && cp "$PROFILE" "$HOME/Library/MobileDevice/Provisioning Profiles/$UUID.mobileprovision"

FAQ

Xcode 16은 프로비저닝 프로필을 어디에 저장하나요? 기본 위치는 ~/Library/Developer/Xcode/UserData/Provisioning Profiles입니다. 레거시 도구는 ~/Library/MobileDevice/Provisioning Profiles를 여전히 읽을 수 있으므로 모든 설치기를 갱신할 때까지 CI 호스트에서는 둘 다 미러링하세요.

Mac mini M4 한 대에 동시 Archive 레인은 몇 개까지? 레인당 120~180 GB NVMe 여유가 있는 두 레인이 실무 기본값입니다. 세 번째 레인은 2 TB 저장소, 공격적 정리, 위 매트릭스의 신중한 메모리 예산이 필요합니다.

SSH에서 codesign이 errSecInternalComponent로 실패하는 이유는? 보통 잠긴 키체인, CI 키체인용 파티션 목록 누락, Xcode 16이 UserData를 먼저 해석하는데 프로필을 레거시 경로에만 둔 경우입니다.

빌드를 빠르게 하려고 레인이 DerivedData를 공유해도 되나요? 릴리스 Archive에는 안 됩니다. 병렬 Archive에서 ModuleCache와 인덱스 저장소가 경합합니다. 레인마다 -derivedDataPath를 쓰고, 패키지를 한 작성자만 해결한 뒤에만 선택적으로 읽기 전용 의존성 캐시를 공유하세요.

탐색 위생을 위해 블로그 목록도움말 센터를 북마크하면 온콜 엔지니어가 채팅 기록을 뒤지지 않고 이 런북을 찾을 수 있습니다.

멀티레인 Xcode 16 Archive에 Mac mini M4 임대가 잘 맞는 이유

Apple Silicon M4는 DerivedData를 격리하고 레인을 솔직히 제한하면 중간 규모 iOS 그래프를 두 개까지 동시에 컴파일할 만큼 통합 메모리 대역폭을 제공합니다. 네이티브 macOS 코드 서명은 에뮬레이트된 Mac 환경을 괴롭히는 하이퍼바이저 키체인 기형을 피하며, 야간 브랜치가 셋 모두 배포 프로필 갱신을 요구할 때 중요합니다. 임대는 급증하는 릴리스 주의 CapEx를 없앱니다. App Store Connect 근접을 위해 도쿄 빌더를, ASEAN 이그레스를 위해 싱가포르를, 미 서부 API 엔드포인트를 위해 미국을 띄웠다가 트레인이 나가면 규모를 줄이세요. 리전 비교는 요금 페이지에서 하고, SSH 리허설은 도움말 센터에서 하며, 헤드리스 임대에 새 저장소를 온보딩할 때는 원격 Archive 워크플로와 이 글을 짝지으세요.

Xcode 16 서명이 예측 가능하게 유지되는 Apple Silicon 임대

HK / JP / KR / SG / US · 헤드리스 SSH · 멀티레인 Archive 준비