디스크 경고로 Jenkins Mac Agent가 오프라인이 됐는데 Workspace 하나를 지워도 여유 공간이 돌아오지 않습니다.
가장 빠른 해법은 전체 작업 디렉터리를 지우는 것이 아니라 Jenkins Remote FS, 사용자 Library, 임시 디렉터리, 아카이브를 따로 조사한 뒤 재생성 가능성에 따라 정리하는 것입니다.

이 글은 Jenkins Mac Agent를 운영하며 디스크 경고와 노드 복구를 담당하는 기업 IT 담당자를 위한 내용입니다. iOS 빌드 효율과 캐시 정책을 맡은 개발 생산성 팀, 빌드 증가량과 대기열을 근거로 Mac 증설을 결정하는 기술 책임자도 대상입니다.

먼저 실패 지점을 네 영역으로 나눕니다

Jenkins 노드의 디스크 감시는 Remote FS와 임시 디렉터리의 여유 공간을 확인할 수 있습니다. 따라서 Jenkins가 디스크 부족을 감지했다는 사실만으로 Workspace를 원인으로 단정하면 안 됩니다. Jenkins 노드 관리 문서에서 노드의 원격 파일 시스템과 디스크 감시 항목을 먼저 확인합니다.

다음 네 영역을 같은 기준으로 기록합니다.

점검 영역 먼저 확인할 항목 바로 지우지 말아야 하는 이유 기본 판단
Jenkins Remote FS Workspace, 다중 작업 디렉터리, 로그 실행 중인 작업이 사용 중일 수 있음 작업 상태와 실제 경로 확인
사용자 Library DerivedData, Swift 패키지 캐시, CocoaPods 캐시 다시 만들 수 있지만 다음 빌드가 느려질 수 있음 재생성 시간과 공유 범위 기록
임시 디렉터리 중단된 빌드의 임시 파일, 도구 설치 잔여물 프로세스가 아직 참조할 수 있음 점유 프로세스 확인 후 유지보수
아카이브 영역 Xcode Archives, dSYM, 배포 자료 장애 분석과 배포 증거가 될 수 있음 배포 담당자의 보존 승인 필요

APFS에서는 Finder가 보여 주는 논리적 파일 크기와 실제로 즉시 회수할 수 있는 공간이 다르게 보일 수 있습니다. 스냅샷, 열린 파일, 시스템 처리 상태가 남아 있을 수 있기 때문입니다. 따라서 Finder의 분류만 보고 삭제 범위를 정하지 말고, 디렉터리별 사용량과 증가량, 마지막 접근 시점을 함께 기록해야 합니다.

Jenkins Mac Agent 디스크 공간이 부족하면 무엇부터 정리해야 합니까?

현재 실행 중인 작업이 없는지 확인한 뒤, 네 영역의 사용량을 비교합니다. 가장 큰 디렉터리가 아니라 “재생성 가능하고 현재 작업이 사용하지 않는 데이터”부터 후보로 올립니다. 사용 중인 Workspace, 서명 자료, 배포 아카이브는 크기가 작아도 우선 보존해야 합니다.

첫 번째 단계: Workspace가 실제 원인인지 확인합니다

Pipeline은 작업마다 Workspace를 할당합니다. 다중 브랜치 작업이나 동시 실행이 활성화되면 같은 작업의 보조 디렉터리가 만들어질 수 있습니다. Pipeline Workspace 동작 문서다중 브랜치 보존 정책 문서를 기준으로 작업 수명과 보존 규칙을 확인합니다.

특히 다음 세 가지를 구분해야 합니다.

  • 현재 실행 중인 빌드가 사용하는 Workspace
  • 삭제된 브랜치나 오래된 작업이 남긴 재생성 가능한 Workspace
  • 사용자 정의 경로와 동시 실행으로 생긴 보조 디렉터리

작업 화면에 보이는 Workspace 경로와 Mac에서 실제로 확인한 경로가 다를 수 있습니다. Pipeline 설정, 사용자 정의 Workspace, 노드별 환경 변수를 함께 확인해야 합니다.

Jenkins Workspace는 빌드가 끝나면 자동으로 삭제할 수 있습니까?

가능하지만 모든 빌드에서 무조건 삭제하는 방식은 위험합니다. 소스와 일반 중간 산출물만 다시 받으면 되는 작업은 cleanWs를 빌드 후 동작으로 검토할 수 있습니다. Workspace Cleanup Plugin 공식 문서처럼 플러그인이 제공하는 조건과 실패 동작을 확인한 뒤, 배포 작업과 일반 검증 작업에 서로 다른 정책을 적용합니다.

자동 삭제를 선택하기 전에 다음 조건을 확인합니다.

  • 빌드가 끝난 뒤 후속 단계가 같은 Workspace를 계속 참조하지 않는지
  • 실패한 빌드의 재현에 필요한 로그와 설정을 별도 저장하는지
  • 의존성 캐시를 Workspace 안에 두고 있지 않은지
  • 삭제 실패가 다음 빌드의 성공 상태를 가리지 않는지

실행 중인 디렉터리를 운영체제 명령으로 일괄 삭제하면 Jenkins 상태와 실제 프로세스 상태가 어긋납니다. 먼저 새 작업을 받지 않도록 노드를 임시로 제외하고, 실행 중인 작업이 끝난 뒤 유지보수 창에서 삭제합니다.

주의: 서명 키, 인증서, Keychain 자료를 일반 캐시와 같은 삭제 스크립트에 넣지 마십시오. 서명 관련 자료는 별도의 책임자와 보존 규칙으로 관리해야 합니다.

두 번째 단계: Xcode 데이터를 재생성 가능성으로 나눕니다

Xcode 관련 데이터는 모두 같은 캐시가 아닙니다. DerivedData는 일반적으로 다시 만들 수 있지만, 삭제 뒤에는 해당 프로젝트를 다시 컴파일해야 합니다. 반면 Simulator Runtime과 플랫폼 구성 요소는 복구에 필요한 다운로드 또는 승인된 설치 경로가 있어야 합니다. Apple의 Xcode 구성 요소 설치 문서를 기준으로 목표 환경에서 복구 방법을 확인합니다.

다음처럼 분류하면 됩니다.

  • DerivedData: 재생성 가능한 빌드 중간 데이터입니다. 다음 빌드의 컴파일 비용과 복구 시간을 기록한 뒤 정리합니다.
  • Simulator 데이터: 테스트 장치와 상태가 포함될 수 있습니다. 실행 중인 테스트가 없는지 먼저 확인합니다.
  • Simulator Runtime: 다시 내려받아야 할 수 있는 플랫폼 구성 요소입니다. 제한된 네트워크 환경에서는 삭제 전에 복구 경로를 검증합니다.
  • 플랫폼 구성 요소: 특정 SDK나 테스트 조합에 필요할 수 있습니다. 현재 파이프라인이 참조하는 버전을 확인합니다.
  • Xcode Archives: 배포와 장애 분석에 필요한 자료입니다. 일반 캐시 보존 규칙을 적용하지 않습니다.
  • dSYM: 배포된 앱의 오류 분석에 필요할 수 있습니다. Apple의 디버그 정보와 dSYM 문서를 확인하고 보존 책임자를 지정합니다.

Xcode DerivedData와 시뮬레이터 파일은 CI 노드에서 안전하게 지울 수 있습니까?

실행 중인 빌드가 없고, 필요한 Runtime과 복구 경로가 확인된 경우에만 일부 정리를 검토할 수 있습니다. DerivedData는 재생성 대상으로 분류할 수 있지만, Simulator Runtime과 Archives까지 같은 스크립트로 삭제해서는 안 됩니다. 정리 전후에 소스 검출, 의존성 복원, 테스트, 서명 배포를 모두 확인해야 합니다.

세 번째 단계: 의존성 캐시와 중복 보관을 추적합니다

Swift Package Manager, CocoaPods, Homebrew, Git LFS, 프로젝트 자체 캐시는 Workspace와 사용자 Library, 외부 산출물 저장소에 동시에 존재할 수 있습니다. Agent에서 지웠는데도 Controller나 산출물 저장소의 중복 자료가 계속 늘면 문제의 위치만 바뀝니다.

각 자료를 다음 네 가지로 기록합니다.

  • 데이터 소유자
  • 다시 만들 수 있는지
  • 여러 작업이 재사용하는지
  • 어떤 조건에서 정리할지

모든 캐시를 영구 보관하면 디스크가 계속 커집니다. 반대로 매번 지우면 네트워크 복구와 빌드 대기 시간이 커질 수 있습니다. 캐시 재생성에 실패했을 때 사용할 내부 저장소와 승인된 의존성 출처도 함께 적어야 합니다.

Jenkins 관리 문서에 따라 Controller, Agent, 산출물 저장소의 역할을 분리해 기록하면 “Agent만 정리했는데 전체 저장 공간은 줄지 않는” 상황을 찾기 쉽습니다.

네 번째 단계: 삭제가 서명과 배포를 깨뜨리지 않는지 검증합니다

정리의 성공 기준을 “몇 기가바이트를 비웠는가”로 두면 안 됩니다. 다음 검증을 순서대로 실행합니다.

  1. 노드를 임시로 작업 대상에서 제외합니다.
  2. 실행 중인 프로세스와 점유 파일을 확인합니다.
  3. 삭제 예정 경로, 데이터 소유자, 복구 방법을 기록합니다.
  4. 현재 작업과 연결된 Workspace, Archives, dSYM, Keychain 자료를 제외합니다.
  5. 재생성 가능한 캐시만 통제된 유지보수 창에서 정리합니다.
  6. 노드를 다시 연결하고 소스를 검출합니다.
  7. 의존성을 복원한 뒤 일반 빌드와 테스트를 실행합니다.
  8. 서명과 배포 파이프라인을 실행합니다.
  9. 노드 재시작 뒤 다시 작업을 받을 수 있는지 확인합니다.
  10. 디스크 감시와 작업 대기열이 정상으로 돌아왔는지 확인합니다.

배포 검증에는 실제 성공한 파이프라인이 필요합니다. 일반 빌드만 통과하고 서명 단계가 빠졌다면 복구가 끝난 것이 아닙니다. Apple의 테스트 및 배포 자료 문서를 기준으로 현재 배포 유형에 필요한 자료를 확인합니다.

다섯 번째 단계: 정리와 증설을 조건으로 분리합니다

Mac 빌드 머신이 반복해서 가득 차면 정리 정책 문제입니까, 용량 부족입니까?

다음 조건으로 판단합니다.

  • 사용하지 않는 Workspace와 중복 캐시가 빠르게 늘면: 보존 규칙, 동시 실행, 작업 종료 정리를 먼저 조정합니다.
  • 정리 후에도 같은 종류의 데이터가 반복해서 다시 쌓이면: 일일 증가량과 한 번의 빌드 최대 사용량을 기록합니다.
  • 동시 실행 수를 낮추면 대기열이 급증하면: 단일 Agent에 작업을 과도하게 몰아넣은 상태인지 확인합니다.
  • 정리 유지보수 때문에 배포 시간이 흔들리면: 일반 빌드 노드와 서명 노드를 분리하는 방안을 검토합니다.
  • 복구 시간보다 새 노드 투입이 빠르고 반복적인 정리가 필요하면: 고정 Mac 노드 또는 필요할 때 추가하는 원격 Mac 용량을 비교합니다.

경고, 작업 수신 중지, 사람의 개입이라는 세 단계로 운영할 수 있습니다. 다만 고정된 여유 공간 수치를 다른 조직에서 그대로 복사하면 안 됩니다. 기준은 단일 빌드의 최대 사용량, 구성 요소 설치 필요량, 복구에 필요한 여유 공간, 동시 실행 수를 기업 기록으로 계산해야 합니다.

노드 용량표에는 다음 항목을 매일 기록합니다.

  • 영역별 사용량과 증가량
  • 정리 실행 횟수
  • 캐시 재생성 시간
  • 빌드 대기 시간
  • 노드 오프라인 시간
  • 실패한 복구와 재배포 결과

이 기록이 있어야 “더 자주 지울지”와 “Mac을 추가할지”를 구분할 수 있습니다.

최종 판단: 기존 Mac을 계속 정리할지, 원격 Mac을 추가할지

현재 방식이 사내 단일 Mac에 의존한다면 물리 장비의 디스크를 직접 증설해야 하고, 유지보수 중에는 빌드 작업을 다른 곳으로 옮기기 어렵습니다. 팀원이 각자 Mac을 보유하는 방식은 사용하지 않는 시간에도 장비 비용이 발생하며, 환경 차이와 권한 회수가 운영 부담이 됩니다. 퍼블릭 클라우드만으로 해결하려 하면 macOS 실행 조건, 연결 방식, 서명 자료 분리 여부를 별도로 검증해야 합니다.

반대로 MACCOME의 원격 Mac은 VNC, SSH 또는 웹 콘솔로 Jenkins Mac Agent 후보 환경에 접근할 수 있고, 완전한 관리자 권한으로 팀의 운영 정책을 적용할 수 있습니다. 기존 노드의 증가량과 대기열을 먼저 측정한 뒤, 짧은 검증용 노드와 지속 운영용 노드를 나누어 비교하는 편이 안전합니다. 원격 Mac 환경 확인에서 현재 조직의 접근 방식과 맞는지 확인하고, Mac mini 기반 구성이 필요하면 Mac mini 주문 환경도 함께 검토할 수 있습니다.

정리 후에도 작업 수신 중지 기준에 반복해서 도달하거나, 유지보수 창이 배포 일정과 충돌한다면 문제는 단순한 캐시 삭제가 아닙니다. 그때는 실제 빌드 기록으로 필요한 용량과 동시 실행 수를 계산하고, 기존 Mac을 계속 압박하는 대신 MACCOME 원격 Mac을 별도 Agent로 추가해 일반 빌드와 서명 작업을 분리하는 편이 운영 안정성 측면에서 더 나은 선택이 될 수 있습니다.