이 글이 답하는 질문은 하나뿐입니다: 단기간 싱가포르에 있는 동안 손에는 울트라북만 있을 때, 72시간 안에 「코드 수정 → 원격 컴파일 → TestFlight」를 Mac Studio를 위탁하지 않고 끝낼 수 있는가?
전제(이후 전편의 기준): 이미 상시 온라인·Xcode 버전 고정·예측 가능한 egress IP를 가진 macOS build node가 있다는 것. 동료 Mac을 잠깐 빌리는 것도, CI가 매번 콜드스타트하는 빈 머신도 아님. Runbook은 「현장에서 어떻게 트리거할지」를 다루며, 안정 build node 없이는 아무리 좋은 SSH 체크리스트도 무너집니다.
아래 타임라인은 팀의 2025-11-13~11-15(싱가포르 시간) hotfix 실록입니다. 식별자는 마스킹했고, 로그는 당시 터미널·GitHub Actions 원문 발췌로 자 환경 대조용입니다.
출발 전 맞출 세 가지:
-
먼저 안정 build node
고정 IP, Xcode 핀, match 단일 쓰기. 출장은 트리거만, 현장에서 환경 구축 금지.
commit + run ID 기록
-
노드는 「산출물 egress」에 맞춤
아태 내부 테스트만 급하면 싱가포르 우선. 북미 ASC·고정 egress는 캐나다 빌드기 유지.
대조표 참고
-
VNC로 하루 종일 코딩하지 말 것
대서양·호텔망에서 화면 공유는 SSH보다 취약. VNC는 키체인 클릭만.
SSH 우선
대조 가능한 시간 앵커(2025-11 출장 실록 발췌)
릴리스 성공일 티켓에 아래 필드를 고정 기록했습니다. 자팀 Runbook에도 남기지 않으면 사후에 「느린 게 네트워크인지 컴파일인지」 구분 불가:
| 필드 | 이번 기록값 | 확인 방법 |
|---|---|---|
| Git commit | 7f2a91c(main) | git rev-parse --short HEAD |
| GitHub Actions | Run #18472930156 · workflow ios-ship.yml | Actions UI → run URL |
| 빌드기 Xcode | 16.2 (16C5032a) · Selected SDK iphoneos18.2 | xcodebuild -version + build log 헤더 |
| 로컬 노트북 Xcode | 16.2(빌드기와 일치) | 동일, 출발 T-48h에 맞춤 |
| Archive 소요 | 11m 34s(클라우드 M4 24GB) | log 말미 ** ARCHIVE SUCCEEDED ** 직전 타임스탬프 차 |
| 동 commit 로컬 Air Clean Build | 38m 12s(1회 실패 후 재실행) | 로컬 대조, 클라우드 편성 근거 |
| TestFlight 처리 | 업로드 4m 08s · ASC 「처리 중」약 22m | altool / API 응답 + ASC 메일 시각 |
| 빌드기 egress | 203.0.xxx.xxx(캐나다 기, 변경 없음) | 빌드기 curl -4 ifconfig.me |
Build description signature: 7f2a91c7e3b2… ExecuteExternalTool …/Xcode.app/Contents/Developer/Toolchains/… ** CLEAN SUCCEEDED ** ** ARCHIVE SUCCEEDED ** [684.123 sec] ← 약 11m 24s(clean 포함) note: Using codesigning identity: Apple Distribution: Acme *** (TEAMID)
당일 밤 싱가포르에서 스마트폰 테더링으로 SSH 트리거.컴파일·업로드 로그는 모두 빌드기에. 노트북에는 Actions run 링크와 commit만. self-hosted runner 사용 시 run ID를 PR 설명에 필히 기록——클라우드 Mac 셀프호스트 runner 기록 습관과 동일.
Runbook이 의존하는 build node는?(출발 전 선정)
출장 주에 현장에서 「Mac 빌릴 수 있나」를 비교하는 게 가장 무섭습니다. 당시 기각·채택안을 표로 정리——제품명은 마지막 열 구현 예일 뿐, 결론 자체가 아님:
| 방식 | 출장 주에 부적합한 이유 | 그래도 필요한 특성 |
|---|---|---|
| Xcode Cloud | match 개인키·커스텀 Fastlane·고정 egress IP 완전 자율 어려움. 트러블슈팅 블랙박스 | PR 검사 병행 가능. hotfix 서명 체인은 자체 node 필요 |
| AWS EC2 Mac | 최소 24h 약정, 쿼터·리전 조정. egress IP 기본 가변 | 실 macOS 하드. AWS 컴플라이언스 팀에 적합 |
| 공유/로테 Mac 클라우드 | 키체인·Derived Data 잔류. 인증서 엇갈림 위험 | 저가. 서명 없는 순수 컴파일만 |
| 사무실 Mac mini | 동료 종료, OS 업데이트, 무인 디스크 교체 | 완전 통제 but 출장 중 7×24 보장 불가 |
| 전용 클라우드 Mac(당팀 채택) | 사전 기동·버전 고정·IP 화이트리스트 필요 | SSH + 고정 egress + 키체인 단일 기. SG/CA 분 DC |
당시 APAC 주간 SSH는 싱가포르 DC M4(사양은 싱가포르 노드 페이지), TestFlight 업로드는 캐나다 기 유지——ASC API 화이트리스트와 match 개인키가 캐나다 egress 203.0.xxx.xxx에 이미 묶여 있었기 때문. 벤더 변경은 가능하나 출장 주는 egress 변경 금지. Hashvps 선택 이유: 갱신해도 IP 불변, 베어메탈 mini(VM 래퍼 아님)——1대 1 IP 요구와 일치. EC2 Mac·사무실 mini가 있어도 「고정 IP + 버전 고정」만 충족하면 아래 Runbook 그대로 적용.
먼저 구분: 「네트워크」인가 「연산」인가
싱가포르 도착 후 「현지 Mac 임대」를 찾는 경우가 많지만, iOS 컴파일·XCTest만이면클라우드 Mac 계약지와 내가 있는 도시는 무관. 창이에서 DC로 SSH는 상하이 출발과 본질 동일. 현지에서 진짜 맞출 것:
- 안정 업링크: 로밍 eSIM 또는 신뢰 테더링으로 SSH 유지(GSMA eSIM 설명. 듀얼 SIM이면 데이터·음성 SIM 분리).
- 타임존 협업: 국내 동료 standup, Code Review 창. 빌드엔 영향 없으나 push 시점엔 영향.
- 컴플라이언스 egress: App Store Connect·기업 프록시 화이트리스트가 보는 건빌드기 egress IP. 호텔 객실 IP 아님.
연산 측: 출발 전 repo clone·인증서 import·Derived Data 경로 고정된 빌드기. 착지 후 git pull과 트리거 스크립트만. 공항에서 Xcode 설치 시작 금지——72시간을 컴포넌트 DL에 씀.
72시간 타임라인(실 타임스탬프)
T-48h · 2025-11-11 상하이: 캐나다 빌드기에서 archive + TestFlight 완주(commit 9e0b44f, Run #18451002201 성공). 양쪽 xcodebuild -version 16.2. SSH 공개키 authorized_keys, 노트북 ~/.ssh/config에 ServerAliveInterval 60.
T-24h · 2025-11-12: 로밍 개통. mosh build-ca 10분 연속 끊김 없음. match 개인키가 캐나다 기만인지 확인(TestFlight 전용기).
T+0 · 2025-11-13 19:10 SGT 창이: 호텔 Wi‑Fi 첫 SSH 실패(아래 장애 ①). 테더링 전환 후 git pull + build 성공 4m 02s(증분, archive 아님).
T+24h · 2025-11-14: 주간 회의. 20:15 SGT 7f2a91c push. 23:41 SGT archive 트리거 → 익일 00:03 SGT ASC 업로드 → 00:25 SGT TestFlight 테스트 가능. PC 앞에 없어도 빌드기·Actions 완주.
T+48h~72h: 고객 데모는 처리된 TestFlight 빌드. 전시회 Wi‑Fi 현장 Archive 금지. 업로드는 App Store Connect API, 노트북 로밍과 무관.
싱가포르 노드 vs 캐나다 노드: 출장 시 선택
리전 상세는 5개 리전 원격 Mac 선택. 출장은 두 가지만:
| 비교 항목 | 싱가포르 / APAC DC 현지 편집 | 캐나다 / 북미 DC 북미 egress 산출물 |
|---|---|---|
| SSH 체감 | RTT 낮음, 로그 추적 쾌적 | 대서양 150~250ms, 충분(컴파일은 원격) |
| TestFlight / ASC | 가능. egress IP 화이트리스트 확인 | 다수 팀 match / API가 북미 IP에 묶임 |
| 적합 작업 | 내부 테스트 빌드, APAC 협업, 주간 반복 | 정식 출시, 공증, 북미 CDN 의존 fetch |
| 출장 중 기 교체 | 불필요. 동일 repo 다중 기 역할 태그 | 불필요. SG 기와 「빌드/업로드」분리 가능 |
당시 싱가포르 도착을 이유로 match 이전 안 함: SG 기는 debug/내부 테스트만, 캐나다 기가 upload 지속. 인증서 이전은 변경 이벤트——출장 주 금지(컴파일 클라우드 오프로드와 역할 분담 동형, 지리만 반전).
연결 체크리스트: 로밍, 호텔 Wi‑Fi, SSH
호텔망 전형 문제: UDP 차단, 5분 idle 끊김, 동일 세그먼트 ARP로 SSH 리셋. 최소 구성:
- 노트북 + 스마트폰 이중 경로: SSH는 테더링, 화상회의는 호텔 Wi‑Fi로 대역 경합 회피.
ServerAliveInterval 60+ServerAliveCountMax 3를~/.ssh/config에.- 장시간 작업은
tmux또는screen. 끊긴 뒤tmux attach로 로그 재개. - 불안정망에서
rsync DerivedData금지——Git만 동기(오프로드 글과 동일 교훈).
출장 2일차 실제 장애 기록(로그 포함)
아래 네 건 모두 2025-11-14 동일 시간대, 발생 순. 가정이 아닌 당시 터미널 원문(경로 마스킹).
① 호텔 Wi‑Fi: SSH idle 끊김
$ ssh build-sg 'cd ~/workspace/MyApp && git pull' client_loop: send disconnect: Broken pipe Connection to build-sg.xxx port 22: Broken pipe
원인: 호텔 NAT가 idle TCP 약 300s에 끊음. 조치: 테더링 + ServerAliveInterval 60. 장시간은 tmux. 이후 동종 미재발.
② Archive 실패: 키체인에 Distribution 인증서 없음
error: No signing certificate "iOS Distribution" found error: No profiles for 'com.acme.myapp' were found ** ARCHIVE FAILED **
원인: 전주 동료가 VNC에서 「로그인」 방식으로 인증서 설치했으나 login keychain에 distribution 미 import. 로컬 노트북은 Xcode 자동 관리로 통과, 클라우드는 match 동기 키체인만——전형적 환경 드리프트.
조치: 캐나다 기에서 bundle exec fastlane match appstore --readonly, security find-identity -p codesigning -v로 Apple Distribution 확인. archive 재실행 성공(상기 11m 34s).
③ 병렬 테스트: Simulator runtime과 Xcode 마이너 불일치
xcodebuild: error: Unable to find a destination matching the provided destination specifier:
{ platform:iOS Simulator, OS:18.1, name:iPhone 16 }
Ineligible destinations: … missing matching iOS Simulator runtime
원인: 빌드기가 지난주 Xcode 16.2(18.2 runtime)로 올랐으나 workflow는 OS:18.1. 조치: ios-ship.yml destination 18.2, .xcode-version repo 커밋——Derived Data 삭제로는 안 고쳐짐.
④ Derived Data 「망가진 것 같음」: 실은 디스크 full
error: unable to attach DB: error: accessing build database "/Users/builder/Cache/DerivedData/…/build.db": database or disk is full
조치: df -h로 / 잔여 6.2GB. 구 .xcarchive·1주 전 브랜치 DerivedData 삭제 후 복구. 「cache corrupt」여도 디스크 full이면 수위 확인 후 rm -rf DerivedData.
실패 패턴 매트릭스(지식 블록 검색용)
| 문제 | 발생 장면 | 클라우드 / 원격 원인 | 조치 |
|---|---|---|---|
| SSH 끊김 | 호텔 Wi‑Fi | NAT idle timeout | 테더링 + ServerAlive + tmux/mosh |
| build 성공·업로드 실패 | ASC / 기업 프록시 | egress IP 미 화이트리스트 | 빌드기 IP 고정. 출장 주 기 교체 금지 |
| local OK / remote fail | archive / 서명 | 키체인 vs match 드리프트 | match readonly + find-identity 검수 |
| Simulator 없음 | CI 야간 테스트 | SDK / runtime 미 lock | .xcode-version + destination 갱신 |
| build.db / cache 오류 | 병렬 다중 브랜치 | 디스크 full이 corrupt 위장 | df -h → archive·구 DerivedData 삭제 |
| 서명 만료 | 분기말 릴리스 | Distribution 인증서 만료 | 14일 전 로테. 출장 주 readonly match만 |
원격 Xcode 최소 폐루프(명령)
착지 당일 「72시간 완주 가능」을 이 한 줄로 검증——파라미터는 TN2339. commit 7f2a91c 바인딩:
ssh build-sg 'set -e
cd ~/workspace/MyApp
git fetch origin && git checkout 7f2a91c && git pull --ff-only
xcodebuild -scheme MyApp -configuration Release \
-derivedDataPath ~/Cache/DerivedData \
-destination "generic/platform=iOS" \
build 2>&1 | tee /tmp/build-7f2a91c.log'
Archive·업로드는 Fastlane lane. 싱가포르에서는 make ship COMMIT=7f2a91c만. Actions Run #18472930156 기록. 빌드기는 self-hosted runner 겸용.
사양·디스크: 출장 주 갑자기 다운그레이드 금지
| 구성 | 메모리 압력 | 디스크 | 권장 |
|---|---|---|---|
| 16GB / 256GB | 병렬 테스트 Swap 쉬움 | 1주 내 full 가능 | hotfix 단일 repo만 |
| 24GB / 512GB | 다수 iOS repo 충분 | 주간 Archives 정리 필요 | 출장 기본 |
| 24GB / 1TB | 여유 | 다중 브랜치 캐시 가능 | monorepo + 다중 Simulator |
짐에 넣을 것(체크리스트)
출장 가방은 의도적으로 가볍게: 안 가져감 16인치 MacBook Pro, 가져감 Terminal 돌아가는 노트북, Lightning/USB-C 테스트 기기, 여분 충전기, 활성화된 로밍 eSIM QR 종이/오프라인 PDF. 빌드기 계정·API Key·match 비밀번호는 1Password 팀 vault지만 오프라인 비상 키트에 빌드기 IP, SSH 포트, on-call 전화——「로밍 불통 + 2FA SMS 미수신」이중 잠금 방지.
고객 데모는 TestFlight 설치본 또는 Ad Hoc. 전시회 Wi‑Fi 현장 Archive 금지. 데모와 릴리스는 별 경로: 데모는 소비자망, 릴리스는 빌드기 고정 egress. 혼용하면 「데모는 되는데 업로드 거절」 착각.
1주 출장 숨은 비용(경영진용)
Mac mini 구매·위탁 또는 현지 임대에는 임대료 외 통관, 전원, OS 재설치, 인증서 import, 팀 재신뢰가 따릅니다. 전용 build node 주간 갱신은 즉시 쓸 수 있는 운영 환경의 대가——Derived Data, match, 고정 IP를 출장 주에 재구축하지 않음.스타트업 Mac 오피스 TCO와 동형: 출장 주 CapEx를 OpEx로, 인증서를 개인 노트북에 흩뿌리지 않음.
자주 무시되는 기회비용: 호텔망 로컬 빌드 1시간은 고객 미팅 1건 상실. 컴파일을 클라우드에 올리면 회의 사이 push, 방에서 로그 확인. 연간 동남아 3~4회 출장하는 입장에서 안정 build node가 「현지 Mac 구매」보다 예측 가능.
FAQ
Mac 필수? Git·SSH 되는 노트북이면 됨(Windows도 가능. Windows + 클라우드 Mac 선택 글 참고). 실기 디버깅 필수면 테스트 기기. 컴파일은 클라우드.
출장 3일차 build node 신규 계약 가능? 가능하나 인증서 import·첫 풀 빌드는 국내 완료. 착지 후 증분만.
싱가포르 DC와 「사람이 SG」 동일 리전 필수? 아님. 동일 리전은 SSH RTT 감소. 북미 스토어는 캐나다 빌드기로 가능.
로밍 데이터로 IPA 전송? 하면 안 됨. IPA는 빌드기에서 ASC 직송. 노트북은 수 MB Git 객체만.
「컴파일 클라우드로」 글과 중복? 그 글은 노트북 버벅임. 본문은 지리 이동 + 네트워크 불확실 하의 Runbook·노드 선택.
OpenClaw / Agent도 옮김? 불필요. Gateway는 기존 캐나다 기 유지. 싱가포르에서는 SSH 빌드 트리거만.
회사 VPN 상시 필수? 정책 따름. VPN이 전체 트래픽 hijack해 SSH 불안정하면 「분할」 신청: 사내만 VPN, 빌드기 SSH 직결. Tailscale로 빌드기만 연결해 호텔 Wi‑Fi 평문 구간 회피하는 팀도 많음.
시차와 릴리스 창? 싱가포르 UTC+8, 미서부와 약 15~16시간 차. 미동부 낮 심사면 SG 오후 archive, 캐나다 빌드기 새벽 자동 upload——태양 따라가는 북미 배치 시프트와 양립. 출장자가 밤새 upload 볼 필요 없음.
본문 commit / Run ID 대조 가능? 내부 repo 실록. 도메인·IP 마스킹. 동일 필드 형식을 자팀 티켓에 남기면 됨, 숫자 일치 불필요.