문제 해결
문제 해결 (Troubleshooting)
Docker Sandboxes에서 만나는 일반적인 문제와 해결 단계를 정리해 드릴게요.
출처: 문서
본문
다음 진단과 복구 단계는 로컬 샌드박스에 적용돼요. 클라우드 연결성과 계정 접근은 sbx --cloud diagnose로 확인하세요. 클라우드 파일, 만료, 네트워크 접근은 클라우드 샌드박스를 참고하세요. 로컬 데몬 재시작과 sbx reset은 클라우드 샌드박스 상태를 복구하지 않아요.
진단 실행 (Run diagnostics)
특정 문제를 파고들기 전에 sbx diagnose를 실행해 CLI 바이너리 누락, 데몬 도달 가능성 문제, CLI/데몬 버전 불일치, 저장 디렉터리 누락, 인증 손상 같은 설치의 일반적인 문제를 확인하세요.
$ sbx diagnose
이 명령은 통과, 경고, 실패한 검사의 요약과 함께 제안된 수정을 출력해요. 머신이 읽을 수 있는 출력은 --output json, GitHub 이슈에 붙여넣기에 적합한 Markdown 스니펫은 --output github-issue를 사용하세요.
샌드박스 데몬 재시작 (Restart the sandbox daemon)
샌드박스 명령이 멈추거나, 데몬에 연결하지 못하거나, 계속 데몬 오류를 반환하면 샌드박스 상태를 재설정하기 전에 샌드박스 데몬을 재시작하세요:
$ sbx daemon restart
그런 다음 실패한 명령을 다시 시도하세요. 데몬 재시작은 샌드박스 데이터를 삭제하지 않아요. 문제가 지속되거나 상태가 손상되었으면 sbx reset을 사용하세요.
샌드박스 재설정 (Resetting sandboxes)
지속적인 문제나 손상된 상태에 부딪히면 sbx reset을 실행해 모든 VM을 중지하고 모든 샌드박스 데이터를 삭제하세요. 이후 새 샌드박스를 만드세요.
샌드박스에 내 프로젝트 파일이 없음
sbx 버전 0.42.0부터 sbx create의 워크스페이스 경로는 선택 사항이에요. 생략하면 마운트 없는 샌드박스를 만들어요. 예를 들어 다음 명령은 호스트 프로젝트 파일을 마운트하지 않고 샌드박스를 만들고 붙어요:
$ sbx create --name <sandbox-name> <agent>
$ sbx run --name <sandbox-name>
반대로 sbx run은 워크스페이스 경로를 전달하지 않으면 현재 디렉터리를 마운트해요:
$ sbx run <agent>
샌드박스의 워크스페이스 구성은 샌드박스가 생성될 때 고정돼요. 기존 마운트 없는 샌드박스의 이름을 재사용하려면, 먼저 보관하고 싶은 파일을 복사해서 제거한 다음 워크스페이스 경로로 다시 만드세요:
$ sbx rm <sandbox-name>
$ sbx run --name <sandbox-name> <agent>
마운트 없음, 직접, 클론 모드 동작은 워크스페이스 선택을 참고하세요.
Kiro, Copilot, Droid 축약어 실패
Docker Sandboxes v0.42에서 sbx run kiro, sbx run copilot, sbx run droid가 실패하는데, 이 에이전트들이 내장 에이전트에서 공개 kit로 이동했고 이 릴리스에서 축약어 이름이 해석되지 않기 때문이에요.
Docker Sandboxes를 v0.43.0 이상으로 업그레이드하면 이 에이전트들을 이름으로 다시 시작할 수 있어요. v0.42에 머물러야 한다면 에이전트의 전체 kit 참조를 사용하세요:
$ sbx run docker.io/sbx/kiro-kit:latest
$ sbx run docker.io/sbx/copilot-kit:latest
$ sbx run docker.io/sbx/droid-kit:latest
에이전트가 패키지를 설치하거나 API에 도달하지 못함
샌드박스는 네트워크 접근 규칙으로 아웃바운드 트래픽을 제어해요. 에이전트가 패키지 설치나 외부 API 호출에 실패하면 대상 도메인이 허용 목록에 없는 경우가 많아요. 어떤 요청이 차단되는지 확인하세요:
$ sbx policy log
그런 다음 워크플로우에 필요한 도메인을 허용하세요:
$ sbx policy allow network "*.npmjs.org,*.pypi.org,files.pythonhosted.org"
모든 아웃바운드 트래픽을 대신 허용하려면:
$ sbx policy allow network "**"
sbx policy allow가 요청을 풀지 못하면 조직이 샌드박스 정책을 중앙 관리해 로컬 규칙보다 우선할 수 있어요. Organization 정책을 참고하세요.
kit 설치 실패: 소스가 허용 목록에 없음
kit 로딩이 소스가 허용 목록에 없다는 메시지로 실패하면:
$ sbx run claude --kit "git+https://github.com/docker/sbx-kits-contrib.git#dir=vale"
ERROR: resolve kits: kit "git+https://github.com/docker/sbx-kits-contrib.git#dir=vale" cannot be installed — its source is not in your allowlist.
sbx는 kit 설치를 기본적으로 Docker Hub(docker.io/)만으로 구성된 소스 허용 목록으로 제한해요. 유지하고 싶은 항목과 함께 kit의 게시자를 kit.allowedSources 설정에 추가하세요:
$ sbx settings set kit.allowedSources '["docker.io/","github.com/docker/"]'
그런 다음 명령을 다시 실행하세요. 로컬 kit나 원격 소스를 허용하는 방법을 포함한 자세한 내용은 kit 소스 제한을 참고하세요.
SSH 및 기타 비-HTTP 연결 실패
SSH 같은 비-HTTP TCP 연결은 대상에 대한 정책 규칙을 추가해 허용할 수 있어요. 프로토콜에 호스트네임이 없을 때 샌드박스가 DNS 해석기에서 호스트네임을 복구하므로 호스트네임 규칙이 이 연결에 동작해요:
$ sbx policy allow network "myhost:22"
DNS 조회 없이 IP 주소로 대상을 도달하면 호스트네임을 복구할 수 없어요. 그 경우 주소 기반 규칙을 사용하세요:
$ sbx policy allow network "10.1.2.3:22"
UDP에는 실험적 UDP 이그레스와 UDP allow 규칙이 필요해요. ICMP는 차단되고 정책 규칙으로 풀 수 없어요.
SSH로 Git 작업을 하려면 Git 서버의 호스트네임이나 IP 주소에 allow 규칙을 추가하거나, 대신 HTTPS URL을 사용하세요:
$ git clone https://github.com/owner/repo.git
호스트에서 실행 중인 서비스에 도달할 수 없음
샌드박스 안에서 127.0.0.1이나 로컬 네트워크 IP로의 요청이 "connection refused"를 반환하면, 그 주소는 샌드박스 VM 안에서 도달할 수 없는 거예요. 샌드박스에서 호스트 서비스에 접근하기를 참고하세요.
Docker 인증 실패
You are not authenticated to Docker 같은 메시지가 보이면 로그인 세션이 만료된 거예요. 대화형 터미널에서 CLI가 다시 로그인하라고 안내해요. 스크립트나 CI 같은 비대화형 환경에서는 sbx login을 실행해 다시 인증하세요.
에이전트 인증 실패
에이전트가 모델 제공자에 도달하지 못하거나 API 키 오류가 보이면, 키가 유효하지 않거나, 만료되었거나, 구성되지 않았을 가능성이 커요. 셸 구성 파일에 설정되어 있는지, source했거나 새 터미널을 열었는지 확인하세요.
자격 증명 프록시를 사용하는 에이전트는 샌드박스 안에서 API 키를 잘못된 값으로 설정하지 않았는지 확인하세요 — 프록시가 아웃바운드 요청에 자격 증명을 자동 주입해요.
자격 증명이 올바르게 구성되었는데도 API 호출이 여전히 실패하면 sbx policy log를 확인하고 PROXY 열을 보세요. transparent 프록시를 통해 라우팅된 요청은 자격 증명 주입을 받지 못해요. 이는 샌드박스 안의 클라이언트(예: Docker 컨테이너 안의 프로세스)가 포워드 프록시를 사용하도록 구성되지 않았을 때 발생할 수 있어요. 자세한 내용은 네트워크 활동 모니터링을 참고하세요.
MCP 서버 스트림 정체
원격 MCP 서버의 HTTP/2 처리가 장기 스트림을 멈추게 하면, --disable-http2로 등록해 HTTP/1.1을 사용하세요:
$ sbx mcp add acme --url https://mcp.acme.com/mcp --disable-http2
예시 URL을 여러분의 MCP 엔드포인트로 바꾸세요. 설정은 이 서버에 대한 이후 연결에 적용돼요. 이 플래그는 --url이 필요하고 --command나 --local과는 쓸 수 없어요. 등록 옵션은 MCP 서버 등록을 참고하세요.
인증서 오류로 API 호출 실패
조직이 HTTPS 트래픽을 검사하는 프록시를 사용하면, 에이전트 요청이 SSL certificate problem: self-signed certificate in certificate chain 같은 인증서 오류로 실패할 수 있어요. 에이전트와 그 SDK가 프록시가 서명한 인증서를 신뢰하도록 조직의 내부 루트 CA를 샌드박스 안에 설치하세요. 인증서 오류가 자격 증명 프록시가 자격 증명을 주입하기 전에 요청을 멈출 수 있어요.
내장 에이전트로 반복 가능한 설정을 만들려면 샌드박스 생성 시 CA를 설치하는 v2 mixin kit을 만드세요. 예시 kit는 내부 CA 인증서 설치를 참고하세요.
.crt 확장자의 PEM 인코딩 인증서를 사용하세요. 트래픽을 둘 이상의 내부 프록시가 서명할 수 있다면 update-ca-certificates를 실행하기 전에 각 프록시의 루트 CA를 설치하세요.
kit로 샌드박스를 만드세요:
$ sbx run claude --kit ./internal-ca/
기존 샌드박스를 업데이트하려면 인증서를 샌드박스에 복사하고 신뢰 저장소를 업데이트하세요:
$ sbx cp ./internal-ca.crt <sandbox-name>:/tmp/internal-ca.crt
$ sbx exec <sandbox-name> -- sudo install -m 0644 /tmp/internal-ca.crt /usr/local/share/ca-certificates/internal-ca.crt
$ sbx exec <sandbox-name> -- sudo update-ca-certificates
[!IMPORTANT] 위처럼
update-ca-certificates로 CA를 시스템 신뢰 저장소에 설치하세요. 샌드박스의 TLS 신뢰 변수(SSL_CERT_FILE같은)를 내부 CA만 가리키도록 오버라이드하지 마세요. 그러면 시스템 번들을 대체해 자격 증명 프록시가 의존하는 신뢰가 깨져forward이그레스 경로의 요청이 실패해요.
CA 설치 후에도 API 호출이 실패하면 sbx policy log를 실행하고 PROXY 열의 이그레스 경로를 확인하세요:
forward: 자격 증명 프록시가 TLS를 종료하고 샌드박스가 이미 신뢰하는 자체 인증서를 제시해요. 이 경로의 요청은 내부 CA가 필요하지 않고, 위에서 설명한 대로 신뢰 변수를 오버라이드하면 깨져요.forward-bypass와transparent: 프록시가 TLS를 종료하지 않고 패킷을 상위 프록시로 전달하므로, 샌드박스가 조직의 인증서를 직접 봐요. 내부 CA 설치가 적용되는 경로가 바로 이 경로예요. 둘의 유일한 차이는 클라이언트가 프록시와 통신하고 있음을 아는지 여부예요.
Docker 빌드 중 인증서 오류
샌드박스의 Docker Engine이 시작한 컨테이너는 자체 신뢰 저장소를 가져요. 샌드박스의 설치된 인증서를 상속하지 않아요. Dockerfile의 HTTPS 다운로드가 self signed certificate in certificate chain으로 실패하면 다운로드 전에 빌드 이미지에 프록시 CA를 설치하세요.
샌드박스 안 셸에서 프록시 CA를 빌드 컨텍스트에 써넣으세요:
$ printf '%s' "$PROXY_CA_CERT_B64" | base64 -d > sbx-proxy-ca.crt
ca-certificates가 설치된 Debian 기반 이미지에서는 HTTPS 요청을 하는 명령 전에 인증서를 복사하고 신뢰 저장소를 업데이트하세요:
FROM python:3.13-slim
COPY sbx-proxy-ca.crt /usr/local/share/ca-certificates/sbx-proxy-ca.crt
RUN update-ca-certificates
샌드박스 안에서 빌드하고 빌드에 프록시 설정을 전달하세요:
$ docker build --build-arg HTTP_PROXY --build-arg HTTPS_PROXY --build-arg NO_PROXY -t my-app .
조직이 TLS도 검사하면 update-ca-certificates 전에 빌드 이미지에 별도의 .crt 파일로 root CA를 설치하세요. 시스템 CA 번들을 온전히 유지해 이미지가 프록시와 공개 인증 기관을 모두 신뢰하게 하세요. 앞의 인증서 문제 해결이 각 CA가 필요한 프록시 경로를 설명해요.
생성된 프록시 인증서를 버전 관리에서 빼두세요. 샌드박스 프록시 CA가 바뀌면 재생성하고 이미지를 다시 빌드하세요.
샌드박스 디스크 공간 부족
샌드박스 루트(/) 파일시스템은 기본 20 GB예요. 늘리려면 샌드박스를 만들기 전에 DOCKER_SANDBOXES_ROOT_SIZE를 설정하세요:
$ DOCKER_SANDBOXES_ROOT_SIZE=40g sbx run claude
DOCKER_SANDBOXES_ROOT_SIZE는 루트 파일시스템 크기를 제어해요. /var/lib/docker의 Docker 데이터 디스크는 독립적이고 기본 10 GB예요. 샌드박스의 Docker 데이터 디스크 크기를 바꾸려면 생성 시 DOCKER_SANDBOXES_DOCKER_SIZE를 설정하세요:
$ DOCKER_SANDBOXES_DOCKER_SIZE=20g sbx run claude
Docker 데이터 디스크는 최소 512 MiB여야 해요. 환경 변수는 기존 볼륨을 크기 조정하지 않아요.
클론 모드 샌드박스에서는 샌드박스 생성 전에 DOCKER_SANDBOXES_CLONED_WORKSPACE_SIZE를 설정해 클론 워크스페이스 볼륨 용량을 구성하세요. 변수는 100g 같은 사람이 읽을 수 있는 크기 문자열을 받아요:
$ DOCKER_SANDBOXES_CLONED_WORKSPACE_SIZE=100g sbx run --clone claude .
큰 저장소에서 파일시스템 작업이 느림
git status, git log, 디렉터리 검사 같은 파일시스템 작업은 워크스페이스 경로를 전달하고 직접 모드를 사용할 때 눈에 띄게 느릴 수 있어요. Virtiofs 캐싱이 이런 워크로드를 빠르게 해요. 클론 모드 샌드박스는 항상 이를 켜므로, 이 튜닝은 직접 모드에만 적용돼요.
Virtiofs 캐싱은 모든 OS에서 기본적으로 활성화돼요. Git 인덱스 손상이나 예상치 못한 파일 내용이 발생하면 킬 스위치로 캐싱을 비활성화하고 샌드박스를 다시 만드세요:
$ DOCKER_SANDBOXES_ENABLE_VIRTIOFS_CACHE=0 sbx run <agent>
WSL에서 클론 모드가 "Git 저장소가 아님" 보고
Windows에서 WSL 파일시스템의(\\wsl.localhost\... 경로) 저장소에 대해 sbx run --clone을 실행하면, 디렉터리가 유효한 Git 저장소임에도 실패할 수 있어요:
> sbx run --clone claude \\wsl.localhost\Ubuntu\home\you\repo
ERROR: --clone requires a Git repository, but \\wsl.localhost\Ubuntu\home\you\repo is not in a Git repository
원인은 Git의 dubious ownership 검사예요. Windows의 Git이 WSL 경계 너머에서 다른 사용자가 소유한 저장소에 접근하면 동작을 거부하므로 기본 저장소 감지가 실패해요:
> git -C \\wsl.localhost\Ubuntu\home\you\repo rev-parse --show-toplevel
fatal: detected dubious ownership in repository at '//wsl.localhost/Ubuntu/home/you/repo'
접근을 허용하도록 Git의 safe.directory 목록에 저장소를 추가한 다음 명령을 다시 실행하세요:
> git config --global --add safe.directory '%(prefix)///wsl.localhost/Ubuntu/home/you/repo'
> sbx run --clone claude \\wsl.localhost\Ubuntu\home\you\repo
✓ Git repository detected: \\wsl.localhost\Ubuntu\home\you\repo
SSH 에이전트 소켓 누락
SSH_AUTH_SOCK이 샌드박스 안에 설정되었는데 ssh-add -L이 No such file or directory를 보고하면, 사용자 정의 템플릿에 socat이 포함되어 있는지 확인하세요. Docker Sandboxes는 호스트 SSH 에이전트에 요청을 전달하는 소켓을 만드는 데 이를 사용해요. OpenSSH 클라이언트 도구만 설치해서는 부족해요.
Ubuntu 기반 사용자 정의 템플릿의 경우 Dockerfile에서 root로 설치하는 패키지에 socat을 추가하고 템플릿을 다시 빌드한 뒤 샌드박스를 만드세요. Docker가 제공하는 샌드박스 템플릿에는 이미 socat이 포함돼 있어요.
소켓이 존재하는데도 포워딩이 여전히 실패하면 SSH 에이전트 설정을 확인하세요.
샌드박스 커밋이 서명되지 않음
Docker Sandboxes는 호스트 에이전트의 SSH 키로 Git 커밋을 서명할 수 있어요. 설정 단계는 커밋 서명을 참고하세요.
포워딩은 기본적으로 활성화돼요. ssh.agentForwardingEnabled와 ssh.agentSocketPath로 포워딩이 활성인지 확인하고 소켓 선택을 점검하세요:
$ sbx settings get ssh.agentForwardingEnabled
$ sbx settings get ssh.agentSocketPath
각 클라이언트의 현재 SSH_AUTH_SOCK을 사용한다면, 의도한 에이전트를 가리키는 셸에서 다시 연결하세요. ssh.agentSocketPath가 경로를 반환하면 활성 호스트 에이전트를 가리키는지 확인하세요. 포워딩이나 소켓 선택을 변경한 후 sbx daemon restart를 실행하세요.
ssh-add -L이 The agent has no identities.를 출력하면 샌드박스가 포워딩된 에이전트에 도달하지만 호스트 에이전트에 로드된 키가 없어요. 호스트 SSH 에이전트에 서명 키를 로드하세요:
$ ssh-add ~/.ssh/id_ed25519
커밋 서명이 호스트에서 동작하는데 샌드박스에서 실패하면, Git이 /Users/me/.ssh/id_ed25519.pub 같은 호스트 파일 경로로 서명하도록 구성되어 있는지 확인하세요. 샌드박스는 호스트 키 파일 경로가 아니라 포워딩된 SSH 에이전트를 사용해요. 인라인 공개 키 형태를 대신 사용하세요:
$ git config --global gpg.format ssh
$ git config --global user.signingkey "key::$(ssh-add -L | head -n 1)"
Git이 ssh-keygen 누락을 보고하면 OpenSSH 클라이언트 도구가 포함된 샌드박스 템플릿을 사용하세요.
git log --show-signature가 gpg.ssh.allowedSignersFile을 구성해야 한다고 보고하면 Git이 SSH 서명을 로컬에서 검증할 수 없어요. 이 검증 구성은 서명된 커밋을 만드는 데 필요하지 않아요. GitHub는 GitHub 계정에 구성된 SSH 서명 키로 커밋을 검증해요.
GPG 및 S/MIME 서명 키는 샌드박스 안에서 사용할 수 없어요. 저장소나 조직이 GPG 또는 S/MIME 서명을 요구하거나, SSH 서명이 구성되지 않았다면 다음 우회책 중 하나를 사용하세요:
-
샌드박스 밖에서 커밋하세요. 에이전트가 커밋 없이 변경만 하게 한 다음 호스트 터미널에서 커밋하고 서명하세요.
-
사후에 서명하세요. 에이전트가 샌드박스 안에서 커밋하게 한 다음 호스트에서 커밋을 다시 서명하세요:
$ git rebase --exec 'git commit --amend --no-edit -S' origin/main이는 브랜치의 각 커밋을 다시 재생하고 로컬 서명 키로 다시 서명해요.
다운그레이드 후 데몬 시작 실패
sbx를 마지막으로 로컬 상태를 관리한 버전보다 오래된 버전으로 다운그레이드하면 데몬이 데이터베이스 버전 불일치로 시작에 실패할 수 있어요:
ERROR: failed to start backend in-process: start backend: creating containerd
server: ... database is at major version 6, but this binary only supports up
to major version 1
새 버전의 sbx가 로컬 데이터베이스를 옛 바이너리가 이해하지 못하는 스키마로 업그레이드했어요. 복구하려면 모든 샌드박스 상태를 재설정하세요:
$ sbx reset --preserve-secrets
이는 모든 VM을 중지하고 모든 샌드박스 데이터를 삭제해요. 이후 새 샌드박스를 만들어야 해요. --preserve-secrets 플래그는 설정한 비밀을 유지해 재구성하지 않아도 돼요.
모든 상태 제거
최후의 수단으로 sbx reset이 문제를 해결하지 못하면 sbx 상태 디렉터리를 완전히 제거할 수 있어요. 이는 모든 샌드박스 데이터, 구성, 캐시된 이미지를 삭제해요. 먼저 sbx reset으로 실행 중인 모든 샌드박스를 중지하세요.
macOS
$ rm -rf ~/Library/Application\ Support/com.docker.sandboxes/
Windows
> Remove-Item -Recurse -Force "$env:LOCALAPPDATA\DockerSandboxes"
Linux
Linux의 샌드박스 상태는 XDG Base Directory 사양을 따르며 세 디렉터리에 걸쳐 있어요:
$ rm -rf ~/.local/state/sandboxes/
$ rm -rf ~/.cache/sandboxes/
$ rm -rf ~/.config/sandboxes/
XDG_STATE_HOME, XDG_CACHE_HOME, XDG_CONFIG_HOME 환경 변수를 사용자 정의했다면 ~/.local/state, ~/.cache, ~/.config를 해당 값으로 바꾸세요.
자동 진단 업로드 활성화
특정 데몬 오류 후 자동 진단 업로드에 옵트인하려면 diagnostics.autoUpload를 yes로 설정하세요:
$ sbx settings set diagnostics.autoUpload yes
자동 번들에는 기본 시스템 정보와 클라이언트, 데몬, 충돌, MCP 로그가 포함돼요. Docker Sandboxes는 인식된 정체성 값과 자격 증명 패턴을 편집하지만, 수집된 로그에는 여전히 사용자 내용이 포함될 수 있어요. 실패한 업로드는 나중 재시도를 위해 로컬 큐에 남아요.
이슈 보고 (Report an issue)
위 단계를 다 시도했는데도 문제가 지속되면 github.com/docker/sbx-releases/issues에 GitHub 이슈를 제출하세요.
Docker의 조사를 돕기 위해 진단 번들을 생성해 이슈 보고 시 공유하세요:
$ sbx diagnose --upload
번들에는 데몬 로그, 진단 검사 결과, 기본 시스템 정보가 들어 있어요. --upload가 확인되면 번들이 Docker 지원으로 업로드되고 명령이 진단 ID를 출력해요. 팀이 업로드된 번들과 대조할 수 있도록 이 ID를 이슈에 포함하세요.