이 글은 고정된 macOS 환경이 필요한 iOS 개발자와 DevOps 엔지니어를 대상으로 합니다. 원격 Mac에 Runner를 등록하고, Xcode와 서명 키를 분리하며, 서비스 자동 실행과 장애 복구까지 확인하는 배포 순서를 설명합니다.
의존성이 Xcode, 코드 서명 또는 Apple Silicon에 묶인 안정적인 고빈도 작업이라면 실제 Mac에 자체 호스팅 Runner를 구축하는 편이 맞습니다. 반대로 가끔 실행하고 고정된 도구 체인이 필요하지 않다면 GitHub가 제공하는 호스팅 Runner가 운영 부담을 줄입니다.
이 글은 Windows나 Linux를 주력 장비로 사용하면서 고정된 macOS CI/CD 환경이 필요한 iOS 개발자를 위한 안내서입니다. Xcode 버전과 서명 키, 캐시, 빌드 대기열을 관리해야 하는 DevOps 엔지니어와 Mac mini 구매와 맥 미니 렌탈 사이에서 검토하는 소규모 팀에도 적합합니다.
최종 업데이트: 2026년 9월 3일. GitHub Runner 절차는 공식 등록 문서, Apple 호환성은 Xcode 시스템 요구 사항을 기준으로 확인했습니다.
시작 전에 실제 Mac Runner가 필요한지 판정합니다
자체 호스팅을 선택할 조건은 다음과 같습니다.
- Xcode 프로젝트를 빌드하거나 iOS 시뮬레이터를 실행해야 합니다.
- 개발 인증서, 프로비저닝 프로파일, Keychain 접근이 필요합니다.
- Apple Silicon 전용 의존성이나 네이티브 도구를 사용합니다.
- 동일한 macOS와 Xcode 조합으로 반복 빌드해야 합니다.
- 빌드가 자주 실행되어 대기 시간과 환경 재설정 비용이 문제가 됩니다.
이 조건이 여러 개 겹치면 실제 Mac 노드가 유리합니다. 반면 외부 기여자가 드물고, 서명 없이 테스트만 하며, 작업 빈도도 낮다면 노드의 패치, 디스크 정리, 장애 복구를 직접 맡을 이유가 적습니다.
보안 경계는 저장소의 신뢰도에 따라 달라져야 합니다. 공개 저장소의 Pull Request나 외부 기여 코드가 서명 키를 가진 Runner에서 실행되도록 기본 설정해서는 안 됩니다. GitHub도 자체 호스팅 Runner에서 신뢰할 수 없는 코드를 실행할 때의 위험을 별도로 안내합니다. Runner 접근 권한과 보안 주의 사항을 먼저 검토해야 합니다.
첫 접속에서 계정과 Runner 등록을 분리합니다
원격 Mac에 접속한 뒤 일상용 관리자 계정을 그대로 Runner 계정으로 쓰지 않습니다. 전용 시스템 계정, 전용 작업 디렉터리, 제한된 파일 권한을 준비합니다. 서명 작업이 없는 테스트 노드라면 관리자 권한을 더 좁게 유지할 수 있습니다.
등록 순서는 다음과 같습니다.
- GitHub 저장소나 조직의 Runner 설정 화면을 엽니다.
- GitHub 공식 화면에서 제한 시간 등록 토큰을 생성합니다.
- macOS와 프로세서 구조에 맞는 Runner 패키지를 선택합니다.
- 전용 작업 디렉터리에 압축을 풀고 등록 스크립트를 실행합니다.
self-hosted,macOS,ARM64와 용도별 라벨을 지정합니다.- 등록이 끝난 뒤 토큰과 임시 파일이 작업 디렉터리에 남지 않았는지 확인합니다.
등록 토큰은 영구 비밀번호가 아닙니다. 화면에서 생성된 토큰을 명령 기록이나 저장소 파일에 넣지 않아야 합니다. 등록 방식과 운영체제별 패키지는 GitHub의 Runner 추가 절차를 기준으로 진행합니다.
Apple Silicon을 지정하려면 runs-on에 운영체제와 아키텍처 라벨을 함께 적습니다. 라벨은 단순한 설명이 아니라 작업을 어느 노드로 보낼지 결정하는 라우팅 조건입니다. GitHub Actions 라벨 라우팅 문서처럼 기본 라벨과 사용자 지정 라벨을 구분해 설계해야 합니다.
첫 작업은 작은 빌드 폐쇄 회로로 확인합니다
처음부터 테스트, 서명, 아카이브와 배포를 한 번에 넣으면 실패 원인을 찾기 어렵습니다. 먼저 라우팅, 체크아웃, 셸 실행과 무서명 빌드만 확인합니다.
예시는 다음과 같이 구성할 수 있습니다.
name: macOS build check
on:
workflow_dispatch:
jobs:
verify:
runs-on: [self-hosted, macOS, ARM64]
steps:
- name: Check runner
run: |
sw_vers
uname -m
xcodebuild -version
- name: Check out source
uses: actions/checkout@v4
- name: Build without signing
run: |
xcodebuild \
-project Sample.xcodeproj \
-scheme Sample \
-configuration Debug \
CODE_SIGNING_ALLOWED=NO \
build
이 예시는 프로젝트 이름과 스킴이 실제 저장소와 일치할 때만 사용할 수 있습니다. 먼저 GitHub 화면에서 Runner가 온라인인지 확인하고, 작업이 지정한 라벨의 노드에서 실행되는지 로그로 확인합니다. 그 다음 테스트, 아카이브, 산출물 업로드를 하나씩 추가합니다.
작업 종료 후에는 다음 항목을 점검합니다.
- 체크아웃 디렉터리에 인증서나 프로파일이 남아 있지 않습니다.
- 임시 로그에 토큰, 비밀번호, 서명 정보가 노출되지 않습니다.
- 빌드 산출물과 의존성 캐시를 의도한 위치에만 보존합니다.
- 다음 작업이 이전 작업의 소스나 Keychain 상태를 무조건 재사용하지 않습니다.
첫날에 Xcode와 서명 범위를 고정합니다
Xcode 26을 사용하려면 노드의 macOS 버전이 해당 Xcode 요구 사항을 충족하는지 먼저 대조해야 합니다. Apple의 시스템 요구 사항 표에서 지원 관계를 확인하고, 경험에 따라 임의의 macOS와 Xcode 조합을 묶지 않습니다. Apple의 Xcode 호환성 표가 버전 판단의 기준입니다.
설정 파일에는 사용할 Xcode를 명시합니다. 여러 버전이 설치된 노드라면 xcode-select 또는 DEVELOPER_DIR로 작업 단위의 개발자 디렉터리를 선택하고, 의존성 파일과 패키지 버전도 저장소에서 고정합니다. Runner 이미지가 우연히 업데이트되어 빌드 결과가 달라지는 상황을 피해야 합니다.
서명 키는 필요한 단계에서만 접근하게 합니다.
- 무서명 빌드와 테스트는 서명 키 없이 실행합니다.
- 아카이브 단계에서만 임시 Keychain을 만들고 잠급니다.
- 인증서와 프로비저닝 프로파일은 저장소에 커밋하지 않습니다.
- 작업이 끝나면 임시 Keychain, 프로파일, 서명 관련 환경 변수를 제거합니다.
- 공개 Pull Request에는 서명 자격 증명을 가진 라벨을 허용하지 않습니다.
캐시는 세 종류로 나눠야 합니다. Swift Package Manager나 CocoaPods 같은 의존성 캐시는 잠금 파일이 바뀌면 키가 달라져야 합니다. 빌드 산출물 캐시는 Xcode와 SDK가 바뀌면 폐기해야 합니다. 작업 디렉터리에 남은 모듈, 로그, 임시 파일은 캐시가 아니라 잔여물이며 주기적으로 지워야 합니다.
첫 주에 서비스 자동 실행과 장애 경로를 고정합니다
터미널을 닫아도 Runner가 계속 실행되게 하려면 제공되는 서비스 설정 절차를 사용합니다. macOS에서는 서비스 등록 뒤 시작 상태를 확인하고, 재시작 후 GitHub 화면에서 다시 온라인으로 전환되는지 검증합니다. Runner 저장소의 서비스 운영과 최신 배포 정보를 함께 확인해야 합니다.
확인할 항목은 다음과 같습니다.
- 서비스가 전용 계정으로 실행됩니다.
- 재부팅 뒤 Runner가 자동으로 시작됩니다.
launchd상태와 진단 로그를 확인할 수 있습니다.- 네트워크 단절 뒤 재연결되는지 확인합니다.
- 디스크 공간 부족과 작업 디렉터리 누적을 감지합니다.
- Runner 소프트웨어와 macOS, Xcode의 수동 유지보수 시간을 정합니다.
Runner 버전은 설치 당시 기억에 의존하지 말고 공식 Releases 페이지에서 확인합니다. 자동 업데이트를 허용할지, 검증 후 수동으로 반영할지는 팀의 변경 관리 방식에 맞춰 결정합니다. 중요한 것은 업데이트 자체보다 업데이트 뒤 Xcode 선택, Keychain 접근, 라벨 라우팅을 다시 검사하는 절차입니다.
작업이 계속 대기하면 라벨 이름과 철자를 먼저 비교합니다. Runner가 오프라인이면 서비스 상태, 네트워크, GitHub 연결 로그를 순서대로 확인합니다. 여러 작업이 한 노드에 몰리면 동시 실행을 무리하게 늘리기보다 저장소나 환경별 Runner 그룹을 나누는 편이 안전합니다. GitHub의 자체 호스팅 Runner 참고 문서는 상태와 운영 조건을 확인할 때 기준으로 사용할 수 있습니다.
배포 전 검수표로 실제 운영 가능성을 판정합니다
다음 목록은 단순 설치 완료가 아니라 운영 투입 여부를 판단하는 검수 기준입니다.
- [ ] Runner가 온라인이며 의도한 저장소 또는 조직 범위에만 등록되어 있습니다.
- [ ]
macOS,ARM64, 용도 라벨이 작업 파일의runs-on조건과 일치합니다. - [ ] 환경 탐색, 체크아웃, 무서명 빌드가 각각 성공합니다.
- [ ] 테스트와 아카이브가 고정된 Xcode로 실행됩니다.
- [ ] 서명 단계에서만 인증서와 프로파일이 접근됩니다.
- [ ] 작업 종료 뒤 임시 Keychain과 민감한 파일이 삭제됩니다.
- [ ] 재부팅 후 서비스가 자동으로 복구됩니다.
- [ ] 오프라인, 대기열 정체, 디스크 부족을 확인할 로그 경로가 있습니다.
- [ ] Runner와 macOS, Xcode를 변경할 승인 및 점검 절차가 있습니다.
- [ ] 신뢰하지 않는 공개 코드가 서명 노드로 라우팅되지 않습니다.
검수 결과는 세 가지로 나누면 됩니다. 모든 항목이 통과하면 자체 호스팅을 계속 사용합니다. 빌드 성공은 하지만 복구나 보안 항목이 부족하면 노드와 워크플로를 보완합니다. 고정된 Xcode나 서명이 필요하지 않고 작업도 드물다면 관리형 Runner로 되돌리는 편이 합리적입니다.
| 운영 조건 | 실제 Mac 자체 호스팅 Runner | 관리형 Runner |
|---|---|---|
| Xcode와 macOS 조합 고정 | 적합 | 제한 확인 필요 |
| Apple Silicon 의존성 | 적합한 라벨로 라우팅 | 제공 조건 확인 필요 |
| 서명 키와 전용 Keychain | 팀이 직접 통제 | 보안 경계 검토 필요 |
| 간헐적인 무서명 테스트 | 유지 관리 부담 | 더 간단한 선택 |
| 장시간 지속 빌드와 전용 큐 | 노드 증설과 감시 필요 | 실행 정책 확인 필요 |
고정된 macOS 도구 체인을 오래 유지해야 한다면 먼저 실제 Mac의 접근성과 재부팅 복구를 확보해야 합니다. 구매한 장비를 직접 관리하면 초기 자산과 수리, 교체, 네트워크 관리 부담이 생기고, 일반 클라우드 Linux 서버는 Xcode와 macOS 전용 서명 흐름을 대신할 수 없습니다. 반대로 단기간 검증이나 팀 규모에 맞춘 임시 노드가 목적이라면 nuvcloud의 한국 원격 Mac 이용 방식과 지역별 원격 Mac 선택 화면을 확인한 뒤, 필요한 Xcode를 지원하는 실제 Mac에서 위 검수표를 실행하는 방법이 현실적입니다.
결국 이 선택은 CI/CD 도구의 문제가 아니라 고정 환경을 누가 운영할지의 문제입니다. 지속적인 빌드 큐와 서명이 필요하면 장기 운영 가능한 원격 Mac을 준비하고, 구매와 유지보수를 맡고 싶지 않다면 필요한 기간만 임대해 Runner를 구성하는 편이 더 유연합니다. 다만 물리 장비 연결이나 장기간의 고정 고부하가 반드시 필요하다면 직접 소유한 Mac이 더 적합할 수 있습니다.
안정적인 원격 맥으로 자체 호스팅 러너를 운영해 보세요
nuvcloud의 원격 맥에서 필요한 맥 운영 환경을 확보하고 아이오에스 빌드 작업을 안정적으로 실행할 수 있습니다.
원하는 맥 사양과 이용 기간을 선택해 프로젝트 규모와 빌드 빈도에 맞는 환경을 구성할 수 있습니다.