맥북(MacBook)을 사용하는 앱 개발자들의 영원한 숙제, 바로 '부족한 용량'입니다. 256GB나 512GB 모델을 사용하다 보면 어느 순간 시스템 데이터(System Data) 항목이 50GB, 100GB를 돌파하며 맥북을 압박해 오기 시작합니다.

용량을 아끼고자 Flutter 프로젝트와 개발 환경을 외장 SSD/HDD로 옮겼는데, 오히려 "Symlink / Permission denied" 빌드 에러가 터지고 시스템 데이터 용량은 계속 늘어나는 기이한 현상을 경험하셨나요?

오늘은 100GB 넘게 증발했던 맥북 시스템 데이터의 숨겨진 원인을 추적하고, 외장하드 환경에서 Flutter 빌드 오류 없이 개발 환경을 구축하는 방법을 완벽하게 정리해 드립니다.


1. 문제의 증상: 용량을 아끼려다 일어난 2가지 비극

🚨 발생 현상 요약:
  • 증상 1 (용량 폭증): 맥북 내장 SSD 용량을 확보하려고 Flutter 프로젝트를 외장 SSD로 옮겨 작업했는데, 정작 맥북의 시스템 데이터 영역이 100GB를 돌파함.
  • 증상 2 (빌드 에러): 외장하드에 위치한 Flutter 앱을 iOS Simulator 또는 CocoaPods 빌드할 때 Operation not permitted, Symlink error, Pod install failure 등 각종 파일 시스템 권한 에러 발생.

2. 원인 분석: "외장하드 포맷 방식"과 "숨겨진 빌드 캐시"

이 문제는 크게 (1) 외장하드의 파일 시스템 형식과 (2) 개발 도구들의 기본 캐시 경로 두 가지 원인이 복합적으로 작용하여 일어납니다.

① 치명적인 함정: exFAT 포맷과 심볼릭 링크(Symlink)의 부재

새 외장 SSD를 구입하면 윈도우와 맥에서 모두 쓸 수 있는 exFAT 포맷으로 기본 설정되어 있는 경우가 많습니다. 하지만 Flutter, Xcode, CocoaPods, Dart 패키지 관리자는 UNIX 방식의 심볼릭 링크(Symlink)와 POSIX 파일 권한(chmod)을 적극 활용합니다.

⚠️ exFAT 포맷의 한계:
exFAT 파일 시스템은 심볼릭 링크와 상세 권한 설정을 지원하지 않습니다. 이 때문에 Flutter 빌드 도중 파이프라인이 깨지고, 빌드 실패 시 생성된 거대한 임시 파싱 파일들이 정리되지 못한 채 맥북 내장 디스크의 /var/folders 및 Temp 영역으로 유실되어 시스템 데이터 용량 폭증을 유발합니다.

② 프로젝트만 옮겨서는 안 되는 이유: 내장 SSD에 남는 캐시들

프로젝트 소스 코드 폴더만 외장하드로 옮긴다고 해서 빌드 캐시까지 따라가지 않습니다. 기본 설정상 다음 경로들은 여전히 맥북 내장 SSD에 무적극 쌓이게 됩니다.

  • ~/Library/Developer/Xcode/DerivedData: Xcode 임시 빌드 아티팩트 (수십 GB 축적)
  • ~/.pub-cache: Dart/Flutter 의존성 패키지 다운로드 저장소
  • ~/Library/Caches/CocoaPods: iOS 팟(Pod) 라이브러리 파일 캐시
  • ~/.gradle: Android 빌드 캐시 및 Gradle 바이너리

3. 단계별 해결 방법 (Troubleshooting)

Step 1. 범인 찾기: 100GB 시스템 데이터의 실제 위치 추적

터미널(Terminal)을 열어 내장 SSD의 대용량 폴더 위치를 상위 순으로 추적합니다.

# 1. 라이브러리 폴더 내 용량 상위 항목 확인
sudo du -sh ~/Library/* | sort -rh | head -n 10

# 2. Xcode DerivedData 용량 확인
du -sh ~/Library/Developer/Xcode/DerivedData

# 3. Flutter Pub 캐시 용량 확인
du -sh ~/.pub-cache

확인해 보면 DerivedData 폴더와 .pub-cache, 그리고 /var/folders 용량이 수십~수백 GB에 달하는 것을 직접 확인할 수 있습니다.


Step 2. 외장하드 포맷 변경 (exFAT ➔ APFS)

외장하드에서 Flutter 및 Xcode 개발을 진행하려면 반드시 APFS (Apple File System) 포맷을 사용해야 합니다.

🚨 주의: 포맷 진행 시 외장하드의 모든 데이터가 삭제되므로, 반드시 기존 데이터를 맥북이나 다른 저장소에 백업한 뒤 진행하세요!
  1. 맥북에서 디스크 유틸리티 (Disk Utility) 실행
  2. 상단 보기 메뉴에서 모든 기기 보기 선택
  3. 외장 SSD의 최상위 드라이브 선택 후 [지우기(Erase)] 클릭
  4. 포맷 방식을 APFS (또는 Mac OS 확장(저널링))으로 지정 후 지우기 진행

Step 3. 캐시 경로를 외장하드로 변경 및 환경변수 설정

내장 SSD의 용량을 아끼기 위해 PUB_CACHE 위치를 APFS로 포맷된 외장하드로 재지정합니다.

# 쉘 설정 파일 열기 (~/.zshrc)
nano ~/.zshrc

# 아래 환경 변수 추가 (외장하드 이름이 ExternalSSD 인 경우)
export PUB_CACHE="/Volumes/ExternalSSD/pub-cache"

# 설정 반영
source ~/.zshrc

Xcode의 DerivedData 저장 경로도 Xcode 메뉴 ➔ Settings (Preferences) ➔ Locations ➔ Derived Data 항목에서 외장하드 내 전용 폴더로 변경해 주면 내장 SSD 용량을 획기적으로 아낄 수 있습니다.

Step 4. 내장 SSD 기존 빌드 찌꺼기 및 스냅샷 완벽 청소

마지막으로 내장 SSD에 오랫동안 쌓여있던 캐시 파일과 APFS 로컬 타임머신 스냅샷을 강제로 정리합니다.

# 1. Xcode DerivedData 전체 삭제
rm -rf ~/Library/Developer/Xcode/DerivedData/*

# 2. CocoaPods 캐시 삭제
pod cache clean --all

# 3. Flutter 기존 캐시 청소
flutter clean

# 4. (선택) 시스템 데이터에 잡히는 APFS 로컬 타임머신 스냅샷 정리
tmutil listlocalsnapshots /
sudo tmutil thinlocalpurgablespace / 100000000000 4

4. 결론 및 요약 체크리스트

💡 맥북 외장하드 개발 환경 핵심 요약:
  • 포맷은 반드시 APFS: exFAT 포맷의 외장하드에서는 Flutter/iOS 개발 시 Symlink 에러와 빌드 찌꺼기 용량 누수가 발생합니다.
  • 캐시 경로 이전: 프로젝트 파일뿐만 아니라 PUB_CACHE와 DerivedData 경로를 외장하드로 지정해야 맥북 내장 SSD가 깨끗해집니다.
  • 주기적인 캐시 정리: flutter clean 및 DerivedData 삭제 구문을 주기적으로 실행해 주면 100GB 넘는 시스템 데이터 경고에서 해방될 수 있습니다.

맥북 용량 부족과 원인을 알 수 없는 Flutter 외장하드 빌드 오류로 스트레스를 받으셨다면, 지금 바로 외장하드의 포맷과 빌드 캐시 경로를 확인해 보세요!