Skip to content

마운트 마이그레이션: 컨테이너 데이터를 외장 드라이브로 옮기기 ​

핵심 내용

~/Library/Containers/와 ~/Library/Group Containers/의 데이터(WeChat 채팅 기록, QQ Music 캐시, App Store 앱 데이터)는 심볼릭 링크로 옮길 수 없습니다. AppPorts 1.9.0부터는 외장 드라이브에 전용 APFS 데이터 볼륨을 만들고 데이터를 복사한 뒤 그 볼륨을 원래 디렉토리에 마운트합니다. 앱에 보이는 경로와 서명은 그대로입니다.

조건은 세 가지입니다. 암호화되지 않은 APFS 외장 드라이브를 사용하고, 앱을 처음 열 때 권한 창에서 허용하며, 앱을 열기 전에 드라이브를 연결해야 합니다.

언제 사용하나요? ​

‘데이터 디렉토리’ → ‘앱 데이터’에서 앱을 선택하면 Containers와 Group Containers 그룹 아래 디렉토리의 버튼이 ‘마이그레이션’ 대신 ‘마운트 마이그레이션’으로 표시됩니다. Application Support, 캐시 같은 다른 그룹과 도구 디렉토리, 사용자 지정 디렉토리는 기존 심볼릭 링크 방식을 그대로 사용합니다.

컨테이너 디렉토리가 특별한 이유와 주 실행 프로그램의 샌드박스 여부만 보지 않는 이유는 컨테이너 데이터, 샌드박스와 서명 신원을 참고하세요.

‘마운트 마이그레이션’을 누르면 ​

AppPorts는 먼저 외장 저장 장치를 읽기 전용으로 검사합니다. 아무것도 변경하지 않고 결과에 따라 다음 단계를 안내합니다.

검사 결과표시 내용가능한 작업
암호화되지 않은 APFS이며 공간 충분이 Mac에서 확보할 공간, 첫 실행 시 권한 허용, 평소 드라이브 연결 등 마이그레이션 설명‘데이터 마이그레이션’으로 시작
exFAT, NTFS, HFS+ 등‘이 외장 저장 장치의 포맷은 exFAT입니다’‘그대로 유지’, ‘다른 위치 선택’, ‘준비 안내 보기’
암호화된 APFS‘이 외장 저장 장치는 암호화되어 있습니다’그대로 유지하거나 암호화되지 않은 APFS 위치 선택
공간 부족필요한 공간과 남은 공간공간을 확보한 뒤 다시 확인하거나 다른 위치 선택
외장 저장 장치를 선택하지 않았거나 연결하지 않음저장 장치 선택 또는 연결 안내‘외장 저장 장치 선택’, ‘다시 확인’

마이그레이션할 수 없어도 아무것도 바꿀 필요는 없습니다. 실제 앱, Application Support, 캐시, 도구 디렉토리는 이 드라이브에 그대로 옮길 수 있습니다. 컨테이너 데이터만 이 Mac에 두면 앱을 평소처럼 사용할 수 있습니다. 나중에 옮기려면 APFS 외장 드라이브 준비를 따르세요.

암호화된 APFS 드라이브를 아직 지원하지 않는 이유

새 데이터 볼륨은 원래 볼륨의 암호를 상속하지 않습니다. 그대로 옮기면 이 Mac에서 FileVault로 보호되던 채팅 기록이 암호 없는 볼륨에 저장됩니다. 자동 잠금 해제와 암호 관리가 완성되기 전까지 AppPorts는 몰래 보호 수준을 낮추지 않습니다. 암호화된 외장 드라이브를 참고하세요.

마이그레이션 전 ​

  • AppPorts를 먼저 ‘응용 프로그램’ 폴더에 넣고 그곳에서 여세요. 로그인 에이전트에는 지속적으로 유효한 프로그램 경로가 필요합니다. 다운로드 폴더나 DMG에서 바로 실행하면 macOS가 임시 App Translocation 경로를 사용할 수 있습니다. 이 경로를 감지하면 새 마운트 마이그레이션을 차단하고 설치를 안내합니다. AppPorts를 이동하거나 업데이트한 뒤 한 번 열면 에이전트 경로를 맞춥니다. 경로가 같으면 에이전트를 다시 로드하지 않습니다.
  • 옮길 앱을 완전히 종료하세요. AppPorts가 확인하며 실행 중인 앱은 마이그레이션할 수 없습니다.
  • AppPorts에 전체 디스크 접근 권한이 필요합니다. 컨테이너 경로에 볼륨을 마운트하는 작업 자체가 시스템의 통제를 받으므로 권한이 없으면 실패합니다.
  • 백업을 고려하세요. 모든 데이터 마이그레이션과 마찬가지로 중요한 데이터는 먼저 별도로 백업하는 것이 좋습니다. 옮긴 데이터는 외장 드라이브에 저장되며 Time Machine은 보통 외장 드라이브를 백업하지 않습니다. 필요하면 ‘시스템 설정 › 일반 › Time Machine’의 옵션에서 이 드라이브가 백업 대상인지 확인하세요.

마이그레이션 중 일어나는 일 ​

  1. 외장 드라이브의 APFS 컨테이너에 새 볼륨을 만들며 /Volumes에 자동으로 마운트하지 않습니다. 이름은 AppPorts-<Bundle ID>-<目录名>-xxxxxx 형식이고, 다른 볼륨과 남은 공간을 공유하므로 크기를 지정할 필요가 없습니다.
  2. 새 볼륨을 ~/Library/Application Support/AppPorts/mounts/ 아래에 임시 마운트하고 AppPorts 복사기로 디렉토리 내용을 복사합니다. 볼륨 루트에 .appports-mount-metadata.plist 표식을 기록한 뒤 마운트를 해제합니다.
  3. 원래 디렉토리의 이름을 바꾸어 같은 볼륨의 안전 백업으로 남깁니다. 원래 경로에 빈 디렉토리를 만들고 볼륨을 마운트한 뒤 올바른 볼륨인지 확인합니다.
  4. ~/Library/Application Support/AppPorts/container-mounts.plist에 마운트 기록을 저장하고 로그인 시 자동 재마운트하는 에이전트를 설치합니다. 마지막에 안전 백업을 삭제합니다.

외장 드라이브 공간이 부족하면 볼륨을 만들기 전에 중단합니다. 마이그레이션이 끝나기 전에 실패하면 AppPorts가 롤백을 시도합니다. 안전하게 롤백을 마칠 수 없으면 사본을 보존하고 남겨 둔 경로를 알려 줍니다.

마이그레이션은 완료했지만 마지막에 로컬 안전 백업을 정리하지 못한 경우에도 마운트된 데이터는 계속 사용할 수 있습니다. AppPorts가 아직 정리하지 못한 백업 경로를 명확히 표시하므로 다시 마이그레이션할 필요가 없습니다.

완료 후 mount 명령으로 볼륨이 컨테이너 경로에 직접 마운트된 것을 볼 수 있습니다.

/dev/disk7s5 on /Users/<user>/Library/Containers/com.tencent.xinWeChat/Data/Documents/xwechat_files (apfs, local, nodev, nosuid, journaled, noowners, nobrowse)

마이그레이션 후 앱을 처음 열 때 ​

시스템이 앱의 이동식 볼륨 파일 접근을 허용할지 묻습니다. ‘허용’을 누르세요. 외장 드라이브의 데이터에 대한 정상적인 macOS 검사이며 한 번만 표시됩니다.

거부하면 앱은 데이터가 없는 것으로 처리해 빈 화면을 표시합니다. 해결하려면 시스템 설정 → 개인정보 보호 및 보안 → 파일 및 폴더(또는 ‘이동식 볼륨’)에서 해당 앱을 찾아 켜세요. 터미널에서 tccutil reset SystemPolicyRemovableVolumes <Bundle ID>를 실행해 다음에 다시 묻게 할 수도 있습니다.

/System/Applications 아래의 시스템 앱에는 권한 창이 나타나지 않고 조용히 거부됩니다. AppPorts는 원래 이런 앱을 마이그레이션하지 않습니다.

일상 사용 ​

앱을 열기 전에 외장 드라이브를 연결하세요. 드라이브가 없으면 마운트 지점은 잠긴 빈 디렉토리(권한 000)입니다. 앱에는 빈 데이터가 보이며 오류를 내거나 새 데이터를 이 Mac에 써서 두 사본을 만들지 않습니다. 연결하면 AppPorts가 볼륨을 자동으로 다시 마운트해 데이터가 돌아옵니다.

이 데이터 볼륨은 평소 Finder에 보이지 않습니다. AppPorts가 nobrowse 옵션으로 마운트하므로 Finder 사이드바와 데스크탑에 표시되지 않습니다. 연결 직후 1~2초 동안 macOS가 먼저 /Volumes에 자동 마운트해 아이콘이 잠깐 보일 수 있지만 AppPorts가 다시 연결하면 사라집니다. 초기 버전으로 옮겨 Finder에 계속 보이는 볼륨은 다음 AppPorts 실행이나 드라이브 연결 때 제자리에서 숨겨지며, 마운트를 해제할 필요가 없습니다. ‘디스크 유틸리티’에서는 AppPorts-… 볼륨이 계속 보입니다. 거기서 지우거나 삭제하지 마세요. 마이그레이션한 데이터가 들어 있는 볼륨입니다.

드라이브를 뽑기 전 앱을 종료한 뒤 AppPorts에서 ‘마운트 해제’를 누르거나 Finder에서 외장 드라이브를 추출하세요. 바로 뽑으면 마지막 몇 초의 쓰기가 손실되고 데이터베이스를 복구해야 할 수 있습니다. 분리 시험에서 APFS 볼륨은 이런 상황에서 마지막 몇 개의 트랜잭션만 잃었습니다. 실험 기록: 드라이브 분리 시험을 참고하세요.

자동으로 다시 연결되는 시점:

  • AppPorts 실행 중: 시작할 때와 새 볼륨이 시스템에 연결될 때마다 온라인이지만 마운트되지 않은 기록을 다시 마운트합니다.
  • AppPorts가 열려 있지 않을 때: 성공적인 마이그레이션 후 로그인 에이전트를 설치합니다. 로그인 시와 외장 드라이브를 연결할 때 조용히 다시 마운트한 뒤 종료합니다. 마지막 기록을 복원하면 에이전트가 자동으로 제거됩니다.
  • 부팅 직후 앱을 열면 10여 초 동안 빈 디렉토리를 볼 수 있습니다. 시스템이 로그인 항목 뒤에 에이전트를 실행하기 때문입니다. 앱을 종료했다가 다시 여세요. 마운트 지점은 계속 비어 있어 앱이 먼저 실행돼도 빈 디렉토리만 읽으며, 새 로컬 데이터를 써서 데이터가 갈라지지 않습니다. 볼륨이 돌아오면 스스로 회복합니다. WeChat에서 3회 모두 회복을 확인했습니다.

macOS 12 등 이전 시스템은 관리자 암호가 필요합니다

macOS 27은 일반 사용자가 자기 디렉토리 안에 볼륨을 마운트하도록 허용하지만 macOS 12에서는 허용되지 않았습니다. 이 오류가 발생하면 AppPorts는 시스템 관리자 암호 창을 표시해 재시도합니다. 보통 마이그레이션당 한 번만 묻습니다. 로그인 에이전트에는 화면이 없어 암호 창을 표시할 수 없으므로 이런 시스템에서는 로그인 후 자동 재마운트가 불가능합니다. AppPorts를 열어 암호를 입력하거나 ‘앱 데이터’에서 ‘마운트’를 눌러야 합니다. 13~26 중 어느 버전부터 허용되는지는 아직 각각 검증하지 않았습니다.

상태와 작업 ​

상태의미가능한 작업
마운트됨원래 디렉토리에 볼륨이 마운트되어 앱이 정상적으로 읽고 씀마운트 해제, 복원
마운트 대기 중볼륨은 온라인이지만 마운트되지 않음. 방금 연결했거나 수동으로 해제한 경우마운트, 복원
외장 드라이브 연결 안 됨데이터 볼륨을 찾을 수 없음. 대부분 외장 드라이브가 연결되지 않은 경우드라이브를 연결하면 자동으로 다시 연결. 이미 연결했는데도 표시되면 아래 문제 해결 참고

복원은 볼륨의 데이터를 이 Mac으로 복사한 뒤 볼륨과 기록을 삭제합니다. 외장 드라이브를 계속 연결해 두세요.

  • 시작 전에 이 Mac의 남은 공간을 검사합니다. 부족하면 중단하며 볼륨과 기록을 그대로 보존합니다.
  • 복사가 끝나면 AppPorts는 먼저 마운트 기록을 정리 대기 정보로 바꾸어 자동 재마운트를 막은 뒤 로컬 디렉토리로 전환합니다. 마운트 해제 후 남은 빈 마운트 지점만 삭제하며 디렉토리를 재귀적으로 삭제하지 않습니다.
  • 로컬 디렉토리로 전환을 마치지 못하면 임시 로컬 사본과 외장 볼륨을 모두 보존합니다. 로컬 사본은 같은 디렉토리의 .appports-restore-staging-… 숨김 폴더에 남습니다. AppPorts가 표시하는 보존 경로와 안내에 따라 처리하세요.
  • 로컬 디렉토리는 복원했지만 외장 볼륨 삭제나 정리 기록 갱신에 실패하면 AppPorts가 복원은 완료했으나 정리는 끝나지 않았음을 명확히 알립니다. 데이터 디렉토리 페이지에서 정리를 다시 시도할 수 있습니다. 마이그레이션이나 복원을 반복하지 마세요.

사본이 아직 있는지 확인할 수 없다면 ‘정리 기록만 삭제’를 선택할 수 있습니다. 이 작업은 로컬 백업이나 외장 볼륨을 삭제하거나 다시 마운트하지 않으므로, 남아 있는 사본은 직접 정리해야 합니다.

마운트 지점에 로컬 파일이 있으면(예를 들어 드라이브가 없는 동안 앱이 다른 방법으로 기록한 경우) AppPorts는 그 데이터를 가리지 않도록 마운트를 거부합니다. 파일을 다른 곳으로 옮긴 뒤 마운트하세요.

AppPorts를 삭제하거나 이동하기 전에 ​

마운트 마이그레이션은 로그인 때마다 볼륨을 연결하는 AppPorts 로그인 에이전트에 의존합니다. AppPorts를 삭제하기 전에 ‘앱 데이터’에서 마운트 마이그레이션한 디렉토리를 ‘복원’하여 이 Mac으로 돌려놓으세요. 복원하지 않고 삭제해도 외장 볼륨의 데이터는 온전하지만 로그인 후 연결해 줄 프로그램이 없어 앱에 빈 디렉토리가 보입니다. AppPorts를 다시 설치하고 한 번 열면 해결됩니다.

업데이트하거나 이동하기만 했다면 새 위치의 AppPorts를 한 번 열면 됩니다. 에이전트가 새 프로그램 위치를 가리키도록 자동으로 조정합니다.

문제 해결 ​

증상처리 방법
드라이브가 연결되어 있는데 ‘외장 드라이브 연결 안 됨’ 표시‘디스크 유틸리티’에서 외장 드라이브에 AppPorts-… 볼륨이 남아 있는지 확인. 있으면 AppPorts 도구 막대에서 새로 고침하거나 드라이브를 다시 연결. 볼륨을 삭제했다면 이 디렉토리 데이터는 외장 드라이브에 없으므로 백업에서 복원해야 함
앱을 열었는데 데이터가 비어 있음먼저 ‘마운트됨’ 상태인지 확인. 아니면 드라이브를 연결하거나 ‘마운트’ 클릭. 마운트됐는데도 비어 있으면 처음 열 때 접근을 거부하지 않았는지 확인
‘마운트’ 시 마운트 지점이 비어 있지 않다고 표시마운트 지점의 로컬 파일이 무엇인지 확인하고 다른 곳으로 옮긴 뒤 다시 마운트
마이그레이션이나 복원 시 백그라운드에서 외장 저장 장치를 연결 중이라고 표시로그인 에이전트가 마운트 중. 몇 초 기다렸다가 다시 클릭

디스크 이미지를 사용하지 않는 이유 ​

exFAT 사용자도 많아 exFAT 드라이브에 APFS 디스크 이미지(sparsebundle)를 두고 마운트하는 방법을 진지하게 시험했습니다. 권한 창이 없고 성능도 비슷하며 어떤 포맷에도 저장할 수 있어 더 좋아 보였습니다.

하지만 쓰기 중 USB 드라이브를 뽑는 시험에서 APFS 볼륨은 마지막 몇 트랜잭션만 잃었고 데이터베이스도 복구할 수 있었지만, 디스크 이미지는 두 번 모두 전체가 열리지 않아 모든 내부 데이터에 접근할 수 없었습니다. 이미지의 ‘목차’가 몇 초마다 다시 쓰이는데 그 도중 분리되면 목차 없는 조각이 되기 때문입니다. 전체 데이터는 실험 기록: 드라이브 분리 시험, 사용자용 설명은 외장 드라이브가 APFS여야 하는 이유를 참고하세요.

따라서 APFS 볼륨만 지원합니다.

기술 세부 정보 ​

자동 재마운트 시점 ​

  • 로그인 에이전트는 ~/Library/LaunchAgents/com.shimoko.AppPorts.container-mount.plist이며 AppPorts --mount-agent를 실행합니다. /Volumes도 감시하므로 외장 드라이브가 마운트되면 다시 실행합니다. 2026-09-22 부팅 측정 순서는 로그인 완료 → 4.6초 후 에이전트 시작 → 18초 후 두 볼륨이 컨테이너 경로에 마운트였습니다. 이전 버전보다 약 19초 빨랐지만 로그인 항목의 앱은 약 3초 만에 실행됐습니다. 시간표와 더 일찍 할 수 없는 이유는 실험 기록: 로그인 전 마운트를 참고하세요.
  • 드라이브가 늦게 나타나도 한 번만 시도하고 끝내지 않습니다. 프로세스 안에서 /Volumes를 감시하고 고정 간격 폴링 대신 다음 실제 변화를 기다립니다. 부팅 시 시스템이 바빠 드라이브 인식에 몇 분이 걸릴 수 있습니다. 2026-09-23에는 부팅 후 2분 33초가 걸렸습니다. 주기적인 폴링은 가장 바쁠 때 diskutil을 불필요하게 실행하거나 앱 시작 시점을 놓칠 수 있습니다. 이벤트가 없으면 20초마다 보완 검사하며 전체 대기 구간은 180초입니다. 기다리는 동안 잠금을 점유하지 않습니다. 볼륨이 나타난 후 마운트까지 약 1초가 걸렸습니다.
  • 마운트 전에 /Volumes/<卷名>를 먼저 확인합니다. 부팅과 연결 때 시스템은 거의 항상 그곳에 먼저 마운트합니다. statfs와 볼륨 루트 표식 읽기 한 번으로 우리 볼륨인지 마이크로초 수준에서 확인하여 diskutil info 한 번을 줄입니다. 2026-09-23 부팅에서는 이 조회에 9초가 걸려 가장 비싼 단계였습니다. 시스템이 볼륨 이름을 바꿨거나 표식이 없는 등 인식할 수 없을 때만 diskutil을 조회합니다.
  • 마운트 뒤에는 검증합니다. diskutil mount -mountPoint에는 함정이 있습니다. 시스템이 이미 /Volumes에 마운트한 볼륨이면 마운트 지점 인수를 무시하고도 mounted를 출력하며 0을 반환합니다. 따라서 매번 실제 대상 경로인지 확인합니다. 다르면 현재 마운트 위치를 다시 조회해 /Volumes에서 해제하고 최대 3회 다시 마운트합니다. 2026-09-21과 09-23에 각각 한 번 발생했으며 당시에는 실패로 판단해 중단했고 WeChat이 빈 디렉토리를 읽었습니다.
  • 자신의 볼륨만 처리합니다. 마운트, 해제, 복원 전에 마운트 지점의 Volume UUID가 기록과 같은지 확인합니다. 다른 볼륨이 있으면 중단하고 해제하거나 덮어쓰거나 삭제하지 않습니다.
  • 에이전트와 AppPorts는 프로세스 간 잠금 ~/Library/Application Support/AppPorts/operation.lock을 공유합니다. AppPorts가 마운트 마이그레이션, 해제, 복원 중이면 에이전트는 최대 120초 양보하며, 기다려도 안 되면 다음 연결이나 로그인 때로 넘깁니다. 반대로 AppPorts도 잠금을 얻지 못하면 작업을 시작하지 않고 나중에 재시도하도록 안내합니다. 잠금은 각 마운트 작업 중에만 유지합니다. 드라이브를 기다리는 몇 분 동안에는 잠금을 잡지 않아 AppPorts 작업을 막지 않습니다.
  • 마이그레이션 기록 파일을 읽지 못하면 빈 기록으로 간주해 덮어쓰지 않습니다. 원본을 보존하고 기록 추가와 삭제를 거부합니다.
  • /etc/fstab은 사용하지 않습니다. 시험에서 UUID= 형식은 작동하지 않았고 장치 번호는 다시 연결하면 바뀝니다. 부팅 시 root가 마운트해도 접근 권한 통제를 받습니다.

볼륨의 Spotlight 색인 ​

시스템은 컨테이너 경로에 마운트된 볼륨을 일반 외장 볼륨으로 취급해 자체 색인을 만듭니다. WeChat 볼륨 두 개의 .Spotlight-V100은 합계 110 MB였으며 부팅 후에도 계속 기록됐습니다. 앱 데이터에 시스템 색인은 필요하지 않으므로 다음과 같이 처리합니다.

  • 볼륨 생성 후 루트에 빈 .metadata_never_index를 기록해 mds가 볼륨 전체를 건너뛰게 합니다. 이미 .Spotlight-V100이 만들어졌으면 함께 삭제합니다.
  • 표식은 볼륨에 따라다니므로 연결 위치 변경이나 마운트 마이그레이션 복원 시 다시 만들 필요가 없습니다.
  • 이 버전 이전에 옮긴 볼륨은 다음 마운트 때 표식을 자동으로 추가합니다.
  • 표식은 이 Mac의 디렉토리로 되돌려 복사하지 않습니다. 복원 시 .metadata_never_index도 .fseventsd, .Spotlight-V100과 함께 건너뜁니다.

직접 확인하는 명령 ​

bash
# 挂载记录
plutil -p ~/Library/Application\ Support/AppPorts/container-mounts.plist

# 当前挂载
mount | grep Containers

# 登录代理
launchctl print gui/$(id -u)/com.shimoko.AppPorts.container-mount

# 卷根有没有防索引标记;系统的索引状态应为 Indexing disabled
ls -la "<挂载点路径>/.metadata_never_index"
mdutil -s "<挂载点路径>"

# 手动重挂(要在有完全磁盘访问权限的终端里执行;旧系统前面加 sudo)
diskutil mount nobrowse -mountPoint "<挂载点路径>" <Volume UUID>

관련 문서 ​

最近更新