~/.claude は Named Volume でプロジェクト完全分離。ローカルの汚染問題がそもそも発生しない
~/.claude/jobs のバックグラウンドジョブ状態は自動では掃除されない。隠しコマンド claude stop <id> か対話TUIで手動クリーンアップが必要
┌─────────────────────────────────────────────────────────┐ │ ホスト (macOS / Windows) │ │ ┌──────────────────────────────────────────────────┐ │ │ │ Docker コンテナ │ │ │ │ │ │ │ │ ┌──────────────────────────────────────────┐ │ │ │ │ │ Claude Code プロセス │ │ │ │ │ │ │ │ │ │ │ │ [Layer 1] Claude Code 組み込み sandbox │ │ │ │ │ │ enableWeakerNestedSandbox: true ← 必須 │ │ │ │ │ │ (bubblewrap はネスト不可のため弱化) │ │ │ │ │ └──────────────────────────────────────────┘ │ │ │ │ │ │ │ │ [Layer 2] iptables allowlist (init-firewall.sh) │ │ │ │ • 許可: api.anthropic.com, npmjs.org, GitHub等 │ │ │ │ • 拒否: それ以外の全アウトバウンド │ │ │ │ • 検証: example.com に繋がらないことを確認 │ │ │ └──────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────┘
Layer 1: Claude Code Sandbox
enableWeakerNestedSandbox: true が必須(bubblewrap がネスト不可のため)Layer 2: iptables Firewall(コンテナ独自)
ip6tables ルールなし。このコンテナは IPv6 なし(loのみ)なので現状問題なしcode.claude.ai 経由でプロキシされるため、コンテナ外の URL も取得可能(設計上の意図)/sandbox コマンド表示バグ(Linux 依存表示)のみ未修正のまま残っている。
* を含むパスで deny が効いていなかった。
settings.json 経由のサンドボックス脱出(Configuration Injection)。SOCKS5 null-byte injection によるネットワーク許可リストバイパスも同時期に修正。
sandbox.bwrapPath / sandbox.socatPath でカスタムバイナリパスを指定可能に。非標準インストール環境に対応。
find コマンドが macOS の vnode テーブルを枯渇させホストをクラッシュさせるバグを修正。
$TMPDIR がサンドボックス外のコマンドにも /tmp/claude-{uid} で上書きされていた問題を修正(bazel / EDR 保護環境で影響)。
claude -p 実行時に「sandbox dependencies missing」の偽警告が出るバグを修正。
.claude/settings.json が絶対パスのシンボリックリンクの場合に Linux sandbox が起動失敗するバグを修正。
/sandbox コマンドが Linux の依存(bubblewrap / socat / seccomp)を表示してしまう。動作には影響しないが混乱の原因。
# devcontainer.json のマウント設定 "mounts": [ "source=claude-code-bashhistory-${devcontainerId}", "target=/commandhistory", ← zsh 履歴の永続化 "type=volume", "source=claude-code-config-${devcontainerId}", "target=/home/node/.claude", ← Claude Code 設定の永続化 "type=volume" ], "workspaceMount": "source=${localWorkspaceFolder}", "target=/workspace", ← ソースコードは bind mount "type=bind,consistency=delegated"
claude-code-config-${devcontainerId} の ${devcontainerId} はワークスペースごとに異なる ID が割り当てられる。
つまり 別のフォルダを開くと自動的に別ボリュームになり、~/.claude が完全分離される。
ローカル運用で問題になる「グローバル汚染」がアーキテクチャとして解決されている(公式ドキュメントでも推奨構成として明記されている)。
${devcontainerId} で分離されるのは ~/.claude の中身(設定・スキル・エージェント)であって、
claude agents(バックグラウンドセッション)の実行状態は別問題。同じボリューム内の
~/.claude/jobs/<id>/ にジョブごとの状態が残り続け、使い終わっても自動では消えない。
kill <pid> しても supervisor daemon が新しい pid で再起動してしまうclaude agents --json --all や claude daemon status--help に出ない隠しコマンド claude stop <id> / claude kill <id> で試す(done 状態には効くが、blocked 状態には効かないことがある)claude agents または claude --resume <sessionId>)での操作が必要な場合がある/sandbox や @anthropic-ai/sandbox-runtime(Docker 不要のプロセス隔離、サンドボックスガイド参照)に移行しても変わらない。
運用で使い終わったジョブをこまめに閉じるしかない。
現場がローカル運用を続ける場合、以下の方法で ~/.claude 汚染を最小化できる。
# .envrc や .zshrc に書く export CLAUDE_CONFIG_DIR=/path/to/project/.claude-config # または direnv を使う場合 # .envrc export CLAUDE_CONFIG_DIR=$(pwd)/.claude-config
これで ~/.claude を使わず、プロジェクトローカルの設定ディレクトリを使うようになる。.gitignore に .claude-config/ を追加すること。
CLAUDE_CODE_VERSION=latest → 特定バージョンに固定(再現性確保)node:20 → node:22-slim に更新(Node 20 は 2026/4 EOL)claude agents バックグラウンドジョブは claude stop <id> で都度クローズclaude agents --json --all で棚卸し(blocked/done放置の掃除)CLAUDE.md・settings.json・Skills の置き場所チェックリストは コンテキスト管理ガイドの棚卸しチェック を参照。
| 観点 | コンテナ(現在) | ローカル(現場) | ローカル + CLAUDE_CONFIG_DIR |
|---|---|---|---|
| ~/.claude 汚染 | なし(devcontainerId で分離) | 発生しやすい | なし(PJ ごとに分離) |
| 環境の再現性 | 高い(Dockerfile で固定) | 低い(OS 依存) | 中(設定のみ分離) |
| ネットワーク制限 | iptables allowlist | なし | なし |
| 導入コスト | 中(Docker Desktop 要) | 低(即開始) | 低(env var 1行) |
| 起動時間 | 初回 1〜2 分、以降数秒 | 即時 | 即時 |
| 推奨場面 | 長期 PJ・セキュリティ重視 | 一時作業・素早い検証 | 現場の暫定対策として |
最終更新: 2026-07-16 ✦ 情報は WebFetch / WebSearch で確認済み ✦ Claude Code changelog・公式 Docs(devcontainer / claude-directory)・GitHub Issues・実運用での動作確認を参照