병합과 배포를 담당하는 분께

다음 병합 작업을 전용 빌드 노드에 맡기세요

먼저 검증 가능한 ipa 파일을 직접 빌드한 다음 CI에 작업을 맡기세요. 기존 파이프라인을 다시 작성할 필요 없이 전원 켜기, 연결, CI 등록, 배포 및 일상적인 운영 순서로 안내합니다.

한 시간 안에 연결 테스트를 마치는 것을 목표로 합니다. 단, 대용량 의존성 다운로드, Xcode 설치, 서명 자료 준비에 따라 시간이 달라질 수 있습니다. 이미 노드가 있다면 연결 점검부터 시작하세요.

시작 전에 필요한 정보를 준비하세요

현재 프로젝트를 실행할 노드부터 준비하세요

가끔 빌드하고 여유 있는 Mac이 있다면 직접 운영하는 편이 더 경제적일 수 있습니다. 하루에도 여러 번 병합하고 전원, 네트워크, 냉각을 직접 관리하고 싶지 않다면 전용 호스팅을 고려해 보세요. OSXPort는 Mac mini 한 대 전체를 제공하며, 노드 한 대는 고객 한 곳만 사용합니다. 가상 머신이 아닙니다.

  1. 01

    프로젝트 기준 확인

    재현 가능한 빌드 명령, 코드 접근 방법, Xcode 버전 요건 및 의존성 잠금 파일을 준비하세요. 먼저 앱 하나, scheme 하나, 브랜치 하나를 정하고, 첫 연결 작업을 전체 배포 시스템 마이그레이션으로 만들지 마세요.

  2. 02

    구성 및 이용 기간 선택

    주문 페이지에서 모델, 지역, 일·주·월·분기 단위 이용 기간을 선택하세요. Port M4 Base는 가벼운 테스트에 적합합니다. 여러 브랜치 빌드와 시뮬레이터 작업에는 Port M4 Plus를 먼저 검토하고, 대규모 다중 target 프로젝트에는 Port M4 Pro를 고려하세요.

  3. 03

    노드 정보 저장

    주문을 완료한 뒤 콘솔에서 노드 주소, 연결 사용자 이름 및 자격 증명을 확인하세요. 실제 사용 가능 여부는 콘솔의 실시간 상태를 기준으로 합니다. 노드 ID를 팀 자산 목록에 기록하고 로그인 비밀번호를 저장소나 티켓 본문에 적지 마세요.

  4. 04

    가까운 지역 선택

    싱가포르, 일본(도쿄), 대한민국(서울), 홍콩, 미국 서부를 선택할 수 있습니다. 팀의 위치뿐 아니라 저장소와 의존성 소스의 위치도 고려하세요. 지역 간 네트워크 성능은 직접 가져오기 및 업로드 작업으로 확인해야 합니다.

세 가지 구성은 Apple Silicon M4 · 통합 메모리 16GB · SSD 256GB, Apple Silicon M4 · 통합 메모리 24GB · SSD 512GB, Apple Silicon M4 Pro · 통합 메모리 64GB · SSD 2TB입니다. 첫 연결 테스트부터 높은 동시 실행 수를 설정하지 말고, 먼저 빌드 1회의 메모리·디스크 사용량과 산출물 크기를 기록하세요.

먼저 머신을 확인한 뒤 파이프라인을 연결하세요

로그인부터 빌드 및 내보내기까지 같은 사용자로 실행하세요

처음 연결할 때는 노드 주소와 사용자를 확인한 다음 개발 도구를 점검하세요. 아래는 예시 세션이며 실제 노드의 출력이 아닙니다. 버전 번호는 형식 예시일 뿐이며, 실제 결과는 현재 노드에서 실행해 확인하세요.

환경을 다시 설치하기 전에 세 단계로 점검하세요

연결 단계:콘솔에서 제공한 주소, 포트 및 사용자 이름으로 연결하세요. 처음 연결할 때 호스트 지문을 확인하고, 예상치 못하게 변경되었다면 검증을 건너뛰지 말고 노드 교체 여부를 먼저 확인하세요. 시간 초과가 발생하면 주소와 네트워크를 확인하고, 인증이 거부되면 사용자와 자격 증명을 확인하세요.

도구 단계:다음 명령으로 xcode-select -p 현재 개발자 디렉터리를 확인하고, xcodebuild -version 으로 버전을 기록하세요. 프로젝트에서 다른 버전을 요구한다면 해당 버전이 설치되어 있는지 확인한 뒤 경로를 명시적으로 전환하세요.

프로젝트 단계:프로젝트 디렉터리에 잠금 파일로 고정된 의존성을 설치한 다음, 기존 빌드 명령을 직접 실행하세요. 대화형 세션에서 로그인에 성공했더라도 백그라운드 runner가 서명 자료에 접근할 수 있다는 뜻은 아닙니다. 이후에는 runner가 실제로 사용하는 계정으로 다시 검증해야 합니다.

예시에서 NODE_USER 와 NODE_ADDRESS 는 콘솔에서 제공된 값으로 설정해야 하며,App.ipa 는 예시 산출물 이름입니다. 프로젝트에서 Bundler로 fastlane을 관리한다면 프로젝트 규칙에 따라 bundle exec fastlane gym을 사용하세요.

osxport · tokyo-node
$ ssh "$NODE_USER@$NODE_ADDRESS"
$ xcode-select -p
/Applications/Xcode.app/Contents/Developer
$ xcodebuild -version
Xcode 16.4
Build version 16F6
$ cd ~/workspace/App
$ fastlane gym
Creating archive
Exporting archive
Successfully exported and compressed dSYM file
Successfully exported and signed the ipa file
Exported ipa: ./build/App.ipa
$ ls -lh ./build/App.ipa

검수 항목: 원격 명령이 정상 종료되고, 버전이 프로젝트 요건에 맞으며, 산출물 경로가 존재하는지 확인하세요. 서명이나 컴파일에 실패하면 첫 오류 전후의 로그를 보존하고 마지막 한 줄만 잘라서 남기지 마세요.

팀에서 이미 사용하는 CI 활용

실행기를 등록하기 전에 수동 작업 하나를 성공시키세요

세 가지 연결 방식 모두 같은 macOS 물리 노드에서 실행됩니다. 아래 인원수는 팀 구성에 대한 권장사항이지 용량 보장이 아닙니다. 빌드 1회의 메모리 사용량, 동시에 실행할 시뮬레이터 수, 디스크 사용량을 기준으로 동시 실행 수를 정하세요.

GitHub Actions 자체 호스팅 runner

적합:워크플로 파일로 협업하는 약 3~15명 규모의 팀에 적합합니다. 별도 작업 스케줄러를 만들 필요 없이 노드를 관리 대상 저장소나 조직에 등록하면 됩니다.

  1. 저장소 또는 조직 설정에서 현재 macOS 및 칩 아키텍처에 맞는 runner 설치 패키지와 등록 명령을 받으세요.
  2. 전용 실행 계정을 사용해 등록하고 팀에서 정한 라벨을 추가한 다음 워크플로의 runs-on 이 해당 라벨을 가리키도록 설정하세요.
  3. 버전 확인과 민감 정보가 없는 빌드 작업부터 실행한 뒤 백그라운드 서비스, 비밀 정보 주입 및 산출물 업로드를 설정하세요.

권장하지 않음:서명 자료가 있는 노드를 신뢰할 수 없는 외부 pull request에 개방하지 마세요. 호스트가 전용이라고 해서 각 워크플로가 서로 격리되는 것은 아닙니다.

실행기 검수 항목 확인

GitLab Runner · shell executor

적합:코드와 권한 관리를 GitLab에 집중한 약 3~30명 규모의 팀에 적합합니다. shell executor는 노드에 설치된 Xcode와 명령줄 환경을 직접 사용합니다.

  1. macOS용 GitLab Runner를 설치하고 프로젝트 또는 그룹에서 제공한 등록 정보로 실행기를 등록하세요.
  2. 다음을 선택하세요: shell executor를 선택하고 전용 라벨을 설정한 뒤, 실행할 수 있는 보호 브랜치와 작업 범위를 제한하세요.
  3. 의존성 복원, 컴파일, 내보내기 및 산출물 저장을 각각 검증할 수 있는 단계로 나누고, 작업 동시 실행은 하나부터 시작하세요.

권장하지 않음:서로 신뢰할 수 없는 고객 저장소를 같은 shell executor에서 함께 실행하지 마세요. 작업 디렉터리와 호스트 권한은 직접 관리해야 합니다.

실행기 검수 항목 확인

Jenkins agent

적합:Jenkins controller와 배포 승인 절차를 이미 갖춘 약 10~30명 규모의 팀에 적합합니다. 노드를 macOS agent로 추가하므로 전체 파이프라인을 마이그레이션할 필요가 없습니다.

  1. controller에서 전용 agent를 만들고 노드 라벨, 전용 작업 디렉터리 및 실행 계정을 지정하세요.
  2. controller 설정에 따라 연결하고, 필요한 Java 버전과 agent 실행 환경의 호환성을 확인한 뒤 상시 실행을 활성화하세요.
  3. 테스트 작업에서 macOS 라벨을 명시적으로 선택하고 환경 변수, 도구 경로 및 산출물 보관 권한을 확인하세요.

권장하지 않음:가끔 한 번 빌드하려고 controller를 새로 만들지 마세요. 이미 가벼운 CI가 있다면 관리 대상을 추가할 필요가 없는 경우가 많습니다.

실행기 검수 항목 확인

실행기가 온라인이어도 다음 네 가지를 확인해야 합니다

개인 대화형 세션이 아니라 runner가 실제로 사용하는 계정으로 검증하세요.
점검 항목검증 방법통과 기준
작업 디렉터리 및 도구다음 명령 실행: whoami,pwd 및 xcodebuild -version사용자, 디렉터리, Xcode 버전이 모두 작업 설정과 일치함
저장소 및 의존성 접근CI에서 주입한 제한된 자격 증명으로 지정된 브랜치를 가져오고 잠금 파일에 따라 의존성을 복원개인 터미널에만 설정된 미선언 토큰이나 경로에 의존하지 않음
코드 서명 사용 가능 여부대화형 입력 없이 아카이브 및 내보내기 완료수동 확인을 기다리는 대화 상자가 없고 자격 증명이 로그에 기록되지 않음
재연결 및 산출물 저장백그라운드 서비스 상태를 확인하고 작업 완료 후 산출물과 로그를 가져옴실행기가 연결을 복구할 수 있고 산출물이 임시 작업 디렉터리에만 남지 않음

한 노드에 여러 개의 관리 대상 작업 진입점을 등록할 수 있지만 CPU, 통합 메모리 및 SSD는 함께 사용합니다. 먼저 빌드 동시 실행 수를 하나로 제한하고 측정 결과를 바탕으로 점차 늘리세요. runner 이름을 여러 개 등록해도 물리 리소스는 늘어나지 않습니다.

Windows에서 코딩하고 macOS에서 빌드하세요

Flutter의 iOS 빌드는 원격에서 실행하세요

Windows에서 코딩, 커밋, 로그 확인은 할 수 있지만 iOS 컴파일과 서명은 클라우드 Mac에서 실행해야 합니다. 전용 노드만으로 유효한 Apple 개발자 프로그램 자격, 서명 인증서, 개인 키 및 앱에 맞는 프로비저닝 프로파일이 제공되는 것은 아닙니다.

  1. 01

    의존성 고정

    동일한 커밋과 잠금 파일을 동기화하고 Flutter, Dart, CocoaPods 및 Xcode의 호환성을 확인하세요. 먼저 flutter doctor -v 를 실행해 툴체인을 확인한 다음 flutter pub get을 실행하세요. 다른 컴퓨터의 절대 경로를 프로젝트에 가져오지 마세요.

  2. 02

    서명 자료 가져오기

    팀에서 승인한 안전한 방법으로 인증서, 개인 키 및 프로비저닝 프로파일을 전달하세요. 실제 빌드 계정에서 접근할 수 있는 전용 키체인에 인증서를 가져오고 프로파일과 내보내기 옵션을 설정하세요. bundle identifier, 팀 식별자 및 배포 유형이 서로 일치하는지 확인하세요.

  3. 03

    실행 후 산출물 가져오기

    다음을 실행하세요. flutter build ipa --release프로젝트에서 내보내기 규칙을 지정해야 한다면 해당 --export-options-plist를 전달하세요. 산출물은 일반적으로 프로젝트의 build/ios/ipa/에 생성됩니다. 실제 출력 경로를 확인한 뒤 CI를 통해 팀의 산출물 저장소에 보관하세요.

  4. 04

    테스트 범위 구분

    원격에서 시뮬레이터 테스트와 자동화 빌드를 실행할 수 있습니다. 실제 기기, 센서 및 상호작용 경험을 확인하는 테스트는 기기에서 계속 진행해야 합니다. React Native 팀도 노드에서 iOS 컴파일을 실행할 수 있지만, 프로젝트에 맞는 스크립트로 의존성을 복원해야 합니다.

캐시는 속도를 높이는 수단이지 백업이 아닙니다. 프로젝트, Xcode 버전 및 의존성 잠금 파일을 기준으로 캐시 키를 설계하세요. 서명 문제가 발생하면 모든 빌드 캐시를 삭제하기 전에 유효 기간, 개인 키와 프로비저닝 프로파일의 일치 여부부터 확인하세요.

먼저 내보내기를 검증한 뒤 업로드를 설정하세요

배포 자격 증명과 노드 로그인 자격 증명을 분리해 관리하세요

TestFlight로 배포하려면 App Store Connect에서 앱에 필요한 설정을 마치고 해당 권한을 갖춰야 합니다. API Key는 업로드 권한을 부여하지만, 컴파일에 필요한 서명 인증서와 프로비저닝 프로파일을 대체하지 않습니다.

설정 순서

  1. 설치 가능한 산출물 확인.먼저 fastlane gym 또는 프로젝트에서 기존에 사용하는 명령으로 아카이브와 내보내기를 완료하고 bundle identifier, 버전 및 빌드 번호를 확인하세요.
  2. API Key 준비.권한이 있는 담당자가 적절한 역할의 App Store Connect API Key를 만들고 Key ID와 Issuer ID를 기록한 뒤 개인 키 파일을 안전하게 보관하세요.
  3. CI에 주입.개인 키와 식별 정보를 팀의 비밀 정보 관리 시스템에 저장하세요. 작업 시작 시 제한된 설정 파일을 만들고 작업이 끝나면 제거하세요. 설정 파일이나 개인 키를 저장소에 커밋하지 마세요.
  4. 업로드 후 처리 상태 확인.pilot을 실행하고 앱 식별자와 업로드 결과를 확인하세요. 업로드에 성공했다고 해서 테스터에게 바로 배포되는 것은 아니므로 이후 처리와 테스트 배포 상태도 확인해야 합니다.

기존 ipa 업로드 명령

fastlane pilot upload \
  --api_key_path "$ASC_API_KEY_JSON" \
  --ipa "$IPA_PATH" \
  --skip_waiting_for_build_processing true

ASC_API_KEY_JSON 은 fastlane 형식으로 만든 임시 API Key 설정 파일을 가리켜야 합니다. IPA_PATH 는 실제 ipa 파일을 가리켜야 합니다. Bundler를 사용한다면 명령 앞에 bundle exec를 붙이세요.

앱 버전, 빌드 번호, 커밋 식별자 및 업로드 결과를 보관하세요. 개인 키 내용이나 전체 인증 설정을 로그에 출력하지 마세요.

업로드 실패 시 오류 유형별로 점검하세요

인증 오류가 발생하면 Key ID, Issuer ID, 개인 키 및 역할 권한을 먼저 확인하세요. 빌드 번호가 중복되면 runner를 다시 설정할 필요 없이 빌드 번호를 변경하세요. 서명이나 앱 식별자 오류라면 아카이브 및 내보내기 단계로 돌아가세요. 컴파일, 서명, 업로드를 각각 별도의 검수 단계로 나누면 작업 전체를 매번 처음부터 다시 실행하는 일을 줄일 수 있습니다.

인수인계 절차를 파이프라인에 기록하세요

노드는 연중 내내 가동되지만 작업은 이전할 수 있어야 합니다

노드는 365일 연중 가동됩니다. 데이터 센터는 전원, 네트워크 및 냉각을 담당하고, 팀은 프로젝트 의존성, 키, 작업 설정 및 데이터 백업을 관리합니다. 하드웨어 문제는 티켓으로 확인하고, 단일 노드를 유일한 데이터 사본으로 간주하지 마세요.

평소에 재구축 체크리스트를 보관하세요

runner 라벨, 도구 버전, 환경 변수 이름, 의존성 설치 절차 및 서명 자료 가져오기 단계를 기록하세요. 개인의 기억에 의존하기보다 자동화 스크립트로 환경을 재구축하는 편이 인수인계하기 쉽습니다.

서명 인증서와 개인 키는 암호화해 백업하세요. 빌드 산출물과 로그는 팀 저장소에 보관해야 합니다. DerivedData와 의존성 캐시는 비용에 따라 백업 여부를 정할 수 있지만, 언제든 다시 생성할 수 있어야 합니다.

연결 검수 체크리스트 다시 확인

문제가 발생하면 먼저 증거를 보존하세요

노드 ID, 발생 시각과 시간대, 마지막으로 성공한 작업 및 오류 요약을 기록하세요. SSH 연결 여부, runner 온라인 여부, 작업 시작 가능 여부를 각각 설명해야 합니다. 단순히 “빌드가 안 돼요”라고만 남기지 마세요.

로그인할 수 있다면 먼저 필요한 데이터와 로그를 내보낸 뒤 새 작업을 일시 중지하세요. 티켓에는 민감 정보를 가린 내용만 포함하고, 문제 해결을 위해 접근 권한을 부여할 때는 범위를 명확히 지정하세요. 개인 키나 전체 비밀번호를 보내지 마세요.

콘솔에 로그인해 문제 신고

노드 교체 후 다시 검수

지원팀이 문제를 확인한 뒤 처리 방법을 티켓으로 안내합니다. 노드를 교체해야 한다면 인도된 정보를 바탕으로 주소와 자격 증명을 업데이트하고 호스트 지문을 다시 확인하세요.

의존성과 서명 자료를 복원하고 runner를 다시 등록하거나 연결한 뒤 최소 빌드 하나를 실행하세요. 새 노드가 작업을 받을 수 있는지 확인한 다음 기존 연결 자격 증명과 더 이상 사용하지 않는 runner 등록을 해지하세요.

연결 단계 다시 점검

일상적인 디스크 정리 전에 보존 정책을 정하세요. 산출물은 릴리스 버전별로 보관하고, 로그는 팀 감사 요건에 따라 보존하며, 캐시는 재생성할 수 있도록 순환 정리하세요. 빌드가 진행 중일 때 작업 디렉터리를 지우거나 전역 Xcode 경로를 바꾸지 마세요.

청구 정보도 노드와 함께 인수인계하세요

릴리스 전에 만료일을 확인하고 마지막 알림에만 의존하지 마세요

일 단위는 첫 테스트나 단기 빌드 작업에 적합하고, 주 단위는 특정 기간에 집중해서 작업할 때 적합합니다. 월·분기 단위는 상시 nightly 빌드에 더 적합합니다. 이용 기간은 실제 총액을 기준으로 선택하고 일 단위 요금을 장기 예산으로 간주하지 마세요.

환경을 변경하기 전에 운영 범위를 확인하세요

팀이 노드를 인수할 때 자주 묻는 여섯 가지 질문

Homebrew와 프로젝트 의존성을 설치할 수 있나요?

일반적인 macOS 프로젝트 방식으로 개발 도구와 프로젝트 의존성을 관리할 수 있습니다. 설치 전에 아키텍처, 설치 경로 및 권한 요건을 확인하고 버전과 설치 절차를 환경 목록에 기록하세요. 처음 연결할 때는 기존 프로젝트의 의존성을 재현하는 데 집중하세요. 모든 도구를 한꺼번에 업그레이드하면 실패 원인이 프로젝트인지 환경 변경인지 판단하기 어렵습니다.

원하는 Xcode 버전을 선택할 수 있나요?

프로젝트 호환성 요건에 맞는 버전을 선택하고 노드에 설치된 버전을 먼저 확인하세요. 다른 버전을 설치해야 한다면 디스크 공간, 다운로드 방법 및 프로젝트 요건을 확인하세요. 특정 버전이 미리 설치되어 있다고 가정하지 마세요. 여러 작업이 노드를 공유한다면 전역 설정을 바꾸는 대신 작업 환경에서 DEVELOPER_DIR를 설정해 실행 중인 다른 작업에 영향을 주지 않도록 하세요.

root 권한이 있나요? runner를 root로 실행해야 하나요?

macOS 그래픽 인터페이스와 명령줄을 모두 사용할 수 있습니다. 관리자 계정과 사용 가능한 sudo 권한은 콘솔에서 제공된 자격 증명으로 확인하세요. 설치 과정에서 추가 권한이 필요하다면 먼저 티켓을 제출해 확인하세요. root로 직접 로그인하는 방식을 기본 연결 방식으로 사용하지 말고, 일반 CI 작업을 높은 권한의 사용자로 실행하지 않는 것이 좋습니다. 빌드, 키 및 작업 디렉터리는 최소 권한 원칙에 따라 각각 관리하세요.

한 팀에서 여러 사람이 노드 한 대를 사용할 수 있나요?

같은 전용 노드를 팀 워크플로에 등록할 수 있지만, 사용자 수가 늘어도 머신의 물리 리소스는 늘어나지 않습니다. 각자 별도 사용자나 명확히 구분된 작업 진입점을 사용하고 동시 실행을 제한하며 환경 변경 시간을 정하세요. 구성원별 빌드 및 서명 권한은 팀에서 직접 관리해야 합니다. 서로 격리된 다중 테넌트 환경으로 간주해서는 안 됩니다.

다른 고객이 캐시를 지울 수 있나요?

머신 전체를 한 고객에게만 제공하므로 다른 고객과 빌드 리소스를 공유하지 않습니다. 다만 팀의 정리 스크립트, 디스크 관리 또는 환경 변경으로 캐시가 영향을 받을 수 있습니다. 캐시는 다시 만들 수 있는 가속 수단으로 사용하고 코드, 서명 자료 및 최종 산출물은 별도로 백업하세요. 노드 교체 시에도 의존성 잠금 파일을 바탕으로 복원할 수 있어야 합니다.

연결이 막히면 티켓에 무엇을 첨부해야 하나요?

노드 ID, CI 유형, 작업의 커밋 식별자, 발생 시각과 시간대 및 첫 오류 전후의 로그를 민감 정보가 드러나지 않도록 가려서 제공하세요. 같은 명령이 대화형 터미널과 runner에서 다르게 동작하는지도 알려주세요. 접근 토큰, 개인 키, 비밀번호 및 민감한 경로에 포함된 업무 정보를 삭제하세요. 지원팀에서 추가 점검이 필요하면 티켓으로 권한 범위를 확인합니다.

실제 작업 하나로 빌드 서버를 검수하세요

먼저 일 단위로 테스트한 뒤 nightly 빌드를 장기간 맡길지 결정하세요. Port M4 Base는 $19.7/일부터 시작합니다. 프로젝트에 맞는 구성을 판단할 수 있도록 커밋 식별자, 빌드 로그 및 산출물을 보관하세요.