
위 이미지는 Gemini Nano Banana를 통해 제작했습니다.
들어가며
Mac mini를 홈서버로 쓰면서, SSH 비대화형 세션에서
docker compose up -d --build를 실행하려 했다.
Docker Desktop의 macOS Keychain 의존성에 막혔고, Colima 전환으로 해결했다.
배경: SSH로 Mac mini를 원격 관리하는 환경
Mac mini를 홈서버로 쓰고 있다. 초기 세팅 때만 키보드와 모니터를 연결했고, 이후 모든 작업은 맥북에서 SSH로 접속해서 처리하는 headless 운용 환경이다.
이 환경에서 자동화하고 싶었던 흐름은 단순했다.
SSH 접속 → git pull → docker compose up -d --build → 배포 완료CI/CD 파이프라인이든, 자동화 스크립트든, 터미널에서 직접 치든 결국 같은 흐름이다. git fetch, health check까지는 문제없이 동작했다. 그런데 docker compose up -d --build 단계에서 멈췄다.
문제: Keychain이 SSH 세션을 차단한다
에러 메시지는 이랬다.
keychain cannot be accessed because the current session does not allow user interaction.
The keychain may be locked; unlock it by running
"security -v unlock-keychain ~/Library/Keychains/login.keychain-db" and try again원인을 추적하니 이런 구조였다.
- Docker Desktop은 이미지를 pull할 때 credential helper를 호출한다.
- macOS의 credential helper(
docker-credential-osxkeychain)는 macOS Keychain에 접근한다. - SSH 비대화형 세션에서는 Keychain UI 상호작용이 차단된다.
- public 이미지(
node:22-alpine등)를 pull할 때조차 credential helper가 호출된다.
Docker Desktop은 GUI 세션이 있는 개발자 워크스테이션을 전제로 설계되어 있다. headless SSH 환경은 고려 대상이 아닌 것이다.
왜 단순 설정 변경으로는 안 됐나
처음엔 간단히 해결할 수 있을 거라 생각했다.
시도 0: security unlock-keychain
에러 메시지가 직접 제안하는 방법이다. SSH 세션에서 Keychain을 먼저 언락하고 docker를 실행하는 방식.
security -v unlock-keychain ~/Library/Keychains/login.keychain-db
docker compose up -d --build
동작은 한다. 하지만 근본적인 해결이 아니다. 매 SSH 세션마다, 혹은 자동화 스크립트 앞에 매번 keychain 비밀번호를 넘겨야 한다. 비밀번호를 스크립트에 하드코딩하거나 별도 시크릿으로 관리해야 하는데, 그 자체가 보안 리스크이고 불필요한 복잡성이다. Docker를 쓰기 위해 Keychain을 여는 건 본말이 전도된 느낌이다.
시도 1: ~/.docker/config.json에서 credsStore 제거
{
"auths": {},
"currentContext": "desktop-linux"
}
결과: 실패. Docker Desktop이 종료/재시작 시 credsStore: "osxkeychain"을 다시 써넣었다. 설정 파일의 소유권이 사실상 Docker Desktop에 있는 셈이다.
시도 2: 격리된 DOCKER_CONFIG로 우회
DOCKER_CONFIG=/tmp/docker-test docker pull node:22-alpine
결과: 실패. Docker Desktop 번들 바이너리(/Applications/Docker.app/.../docker)가 config와 무관하게 credential helper를 호출했다.
시도 3: Homebrew docker CLI 직접 사용
/opt/homebrew/bin/docker pull node:22-alpine
결과: 실패. ~/.zshenv에서 Docker Desktop의 PATH가 최상위에 설정되어 있어서 docker-credential-osxkeychain이 여전히 PATH에서 발견되고 호출되었다.
# ~/.zshenv 내용
export PATH="/Applications/Docker.app/Contents/Resources/bin:$PATH"
문제의 근본은 Docker Desktop이 세 겹으로 keychain 의존성을 심어놓는다는 것이었다.
config.json의credsStore- Docker CLI 바이너리 자체
- PATH에 주입된 credential helper 바이너리
하나만 우회해서는 다른 경로로 keychain 호출이 발생한다. Docker Desktop을 유지한 채로 keychain 의존성만 끊는 건 사실상 불가능했다.
해결: Docker Desktop → Colima 전환
Colima란?
Colima는 macOS에서 Docker 컨테이너를 실행하기 위한 경량 런타임이다.
macOS에서는 Docker 컨테이너를 네이티브로 실행할 수 없다 — Linux 커널이 필요하기 때문이다. 그래서 반드시 Linux VM이 필요하고, 그 VM을 누가 관리하느냐의 차이다.
| Docker Desktop | Colima | |
|---|---|---|
| VM 관리 | Docker사 자체 VM + GUI | Lima 기반 경량 VM |
| GUI | 메뉴바 아이콘, 대시보드 | 없음 (CLI only) |
| Keychain 의존 | 있음 | 없음 |
| SSH 비대화형 자동화 | 불가 | 가능 |
| 호스트 오버헤드 | ~1-2GB (Electron GUI + 부가 서비스) | 최소 (CLI 프로세스만) |
| docker CLI 호환 | 100% | 100% (동일 CLI) |
| 라이선스 | 대규모 기업 유료 | 오픈소스 무료 |
호스트 오버헤드는 VM에 할당하는 메모리와 별개다. Docker Desktop은 Electron 기반 GUI, 자동 업데이트, 확장 기능 등 부가 서비스가 백그라운드에서 돌아가면서 추가 메모리를 소비한다. Colima는 VM과 Docker 데몬만 실행하므로 호스트 측 오버헤드가 훨씬 적다.
핵심: 기존 docker compose 명령어가 100% 그대로 동작한다. 앱 코드 변경이 필요 없다.
왜 OrbStack이 아니라 Colima인가
macOS Docker 런타임으로 OrbStack도 좋은 선택지다. GUI가 있으면서도 가볍고, 특히 macOS ↔ 컨테이너 간 파일 시스템 마운트 성능이 Docker Desktop이나 Colima 대비 눈에 띄게 빠르다. 볼륨 마운트가 많은 개발 환경이라면 체감 차이가 크다.
이번에 Colima를 선택한 이유는 단순하다. headless 홈서버에서 GUI가 필요 없고, 오픈소스 무료이며, brew services로 부팅 시 자동 시작이 간단하다. OrbStack은 개인 무료이지만 상용 라이선스 구조가 있고, GUI 앱 기반이라 headless 환경에서는 Colima가 더 자연스럽다.
전환 과정
1단계: Colima 및 docker CLI 설치
brew install colima docker docker-compose
2단계: Docker Desktop PATH 제거
# ~/.zshenv에서 이 줄 제거:
# export PATH="/Applications/Docker.app/Contents/Resources/bin:$PATH"
3단계: ~/.docker/config.json 정리
{
"auths": {},
"currentContext": "colima",
"cliPluginsExtraDirs": [
"/opt/homebrew/lib/docker/cli-plugins"
]
}
credsStore 항목을 완전히 제거한다. Docker Desktop이 다시 써넣는 것을 방지하기 위해 Docker Desktop 자체를 더 이상 실행하지 않는다.
4단계: Docker Desktop 중지, Colima 시작
osascript -e 'quit app "Docker Desktop"'
colima start --cpu 4 --memory 4 --disk 60
--cpu와 --memory는 Linux VM에 할당할 리소스다. Mac mini의 전체 자원에서 호스트 OS 몫을 남기고 배분하면 된다. 예를 들어 8GB Mac mini라면 VM에 4GB 정도를 주고 나머지를 macOS에 남겨두는 식이다. --disk는 컨테이너 이미지와 볼륨이 쌓일 공간이므로, 이미지를 여러 개 쓴다면 넉넉하게 잡는 게 좋다.
5단계: 부팅 시 자동 시작 설정
brew services start colima
6단계: 검증
# SSH 세션에서:
which docker
# /opt/homebrew/bin/docker (Docker Desktop이 아님)
docker pull node:22-alpine
# 성공 — keychain 에러 없음
docker compose version
# Docker Compose version v2.x.x
Ubuntu 서버에서는 왜 이 문제가 없는가
Ubuntu(Linux)에서는 Docker Engine이 OS 커널 위에서 직접 실행된다.
[컨테이너] → Docker Engine → Linux 커널VM도 없고, GUI도 없고, Keychain도 없다. SSH 비대화형 세션에서 docker compose up -d --build가 아무 문제 없이 동작하는 이유다.
macOS에서는 구조가 다르다.
[컨테이너] → Docker Engine → Linux VM → macOSVM 관리자(Docker Desktop)가 macOS의 GUI/Keychain에 의존하면 SSH 자동화가 막힌다. Colima는 이 의존성 없이 VM을 관리하기 때문에 Linux 서버와 동일한 자동화 경험을 제공한다.
정리
| 항목 | Before | After |
|---|---|---|
| 런타임 | Docker Desktop | Colima |
SSH docker pull |
keychain 에러 | 정상 동작 |
SSH docker compose build |
불가 | 가능 |
| 자동화 스크립트/CI 배포 | 불가 | 가능 |
| 부팅 시 자동 시작 | Docker Desktop (GUI 필요) | brew services (headless) |
'Infra' 카테고리의 다른 글
| OSI 7계층, 택배 한 번 시켜보면 이해됩니다!!! (1) | 2026.04.07 |
|---|---|
| 카카오 클라우드 GPU 서버 설치 및 설정 가이드 (Docker + GPU 최적화) (2) | 2025.05.30 |
