はじめに
devcontainerでClaude Codeを使うと、コンテナをリビルドするたびに認証情報と会話履歴が消えてしまう——この問題への対策として、こちらの記事で紹介されているマウント設定を導入しました。
本記事では、その設定が本当に効いているのかをコンテナ内部から検証した結果と、そこから一歩進めて
- 別のプロジェクトのdevcontainerでも使えるのか?
- 新しいプロジェクトでコンテナをreopenした時点で自動的にこの設定を適用できるのか?
を調べた結果をまとめます。
前提となる設定
参考記事のとおり、devcontainer.json に以下を設定しています。
{
"name": "blazor-sample",
"image": "mcr.microsoft.com/devcontainers/dotnet:1-10.0-noble",
"workspaceMount": "source=${localWorkspaceFolder},target=/code/blzrapp,type=bind,consistency=cached",
"workspaceFolder": "/code/blzrapp",
"features": {
// Claude Codeのdevcontainer Featureを有効化
"ghcr.io/anthropics/devcontainer-features/claude-code:1.0": {}
},
// ↓↓↓ このマウント設定がポイント ↓↓↓
"mounts": [
// 履歴や設定が保存されるディレクトリをマウント
"source=${localEnv:HOME}/.claude,target=/home/vscode/.claude,type=bind,consistency=cached",
// 認証情報が保存されるファイルをマウント
"source=${localEnv:HOME}/.claude.json,target=/home/vscode/.claude.json,type=bind,consistency=cached"
],
"remoteUser": "vscode"
}
環境はWSL2上のDocker + VS Code Dev Containers拡張です。
検証:本当に永続化されているのか?
「設定を書いた」と「効いている」は別物なので、コンテナの中から確かめます。
1. マウントが認識されているか
$ mount | grep -i claude
/dev/sdd on /home/vscode/.claude type ext4 (rw,relatime,...)
/dev/sdd on /home/vscode/.claude.json type ext4 (rw,relatime,...)
/home/vscode/.claude と /home/vscode/.claude.json の両方が、コンテナのオーバーレイFSではなくホスト(WSL側)のext4からのバインドマウントとして認識されています。
2. 会話履歴がマウント先に書き込まれているか
$ ls -lt /home/vscode/.claude/projects/-code-blzrapp/
-rw------- 1 vscode vscode 112282 Jul 17 01:01 7caf7fb6-xxxx-xxxx-xxxx-xxxxxxxxxxxx.jsonl
今まさに進行中のClaude Codeセッションの会話ログ(.jsonl)が、マウントされた領域にリアルタイムで書き込まれていました。つまり会話はコンテナ内ではなくホスト側に保存されていることが確認できます。
3. リビルド後も同じ履歴を参照できるか
履歴の保存先は ~/.claude/projects/ 配下に作業ディレクトリのパスから決まるキー(/code/blzrapp → -code-blzrapp)で分かれています。devcontainer.json で workspaceFolder を固定しているので、リビルド後も同じキーを参照します。
実際に「Dev Containers: Rebuild Container」を実行してからClaude Codeで /resume すると、リビルド前の会話が一覧に出てきて続きから再開できました。永続化は本当に効いています。
別のプロジェクトでも使えるのか?
結論:使えますが、自動ではありません。 この永続化はClaude Code Feature自体の機能ではなく、devcontainer.json に明示的に書いたマウント設定によるものなので、新しいプロジェクトにも同じ mounts ブロックを書き写す必要があります。
その際のポイントは3つ:
-
targetのパスはコンテナ側ユーザーのホームに合わせる
remoteUser: vscodeなら/home/vscode/...、Node系イメージなら/home/node/...、rootなら/root/...。ここがズレると全く効きません。 -
認証情報は共有される
ホストの~/.claudeと~/.claude.jsonを全プロジェクトで共有するので、新しいコンテナでログインし直す必要はありません。 -
履歴はプロジェクトごとに分かれる
前述のとおり作業ディレクトリのパスごとに履歴が分かれるため、会話が混ざることはありません。逆に、複数プロジェクトでworkspaceFolderを同じパスにすると履歴が混ざるので、プロジェクトごとに一意なパスにしましょう。
また、コンテナユーザーのUIDがホストと一致しない場合に備えて、postCreateCommand で所有権を直しておくと安全です。
#!/bin/sh
mkdir -p "$HOME/.claude"
sudo chown -R "$(id -u):$(id -g)" "$HOME/.claude"
新しいプロジェクトでreopenした時点で自動適用できるのか?
毎回コピペするのは面倒なので、「ユーザー設定で全devcontainerに自動適用」できないか調べました。
残念なお知らせ:defaultMountsは存在しない
まさにこの用途の dev.containers.defaultMounts という設定はVS Codeに機能リクエストがありましたが、「not planned」でクローズ済みです。ユーザー設定でマウントだけを全コンテナに配る公式の手段はありません。
回避策:defaultFeatures + 自作Feature
ただし、抜け道があります。
- VS Codeのユーザー設定
dev.containers.defaultFeaturesに登録したFeatureは、どのプロジェクトのコンテナにも自動で追加される - そしてDev Container Featureは自身のメタデータに
mountsを宣言できる
つまり「マウントを含む自作Featureを作って defaultFeatures に登録する」ことで実質的に自動化できます。
自作Featureの devcontainer-feature.json はこんなイメージです:
{
"id": "claude-persist",
"version": "1.0.0",
"name": "Claude Code設定の永続化",
"mounts": [
{ "source": "${localEnv:HOME}/.claude", "target": "/claude-config", "type": "bind" }
],
"containerEnv": { "CLAUDE_CONFIG_DIR": "/claude-config" }
}
ここでのポイントは、/home/vscode のようなユーザー名依存のパスを避けて固定パス(/claude-config)にマウントし、環境変数 CLAUDE_CONFIG_DIR でClaude Codeにその場所を教えること。これでコンテナのユーザーが vscode でも node でも root でも、同じFeatureがそのまま使えます。
これを feature-starter テンプレートを使ってghcr.ioに公開し、VS Codeのユーザー settings.json に登録すれば完成です:
"dev.containers.defaultFeatures": {
"ghcr.io/<あなたのGitHub名>/devcontainer-features/claude-persist:1": {}
}
以後、どのプロジェクトでdevcontainerをreopenしても自動でマウントが入ります。
この方式の注意点
-
CLAUDE_CONFIG_DIR方式では認証ファイル.claude.jsonも$CLAUDE_CONFIG_DIR配下(つまり~/.claude/.claude.json)に置かれるため、ホスト直下の~/.claude.jsonとは別管理になります。初回に一度だけログインし直せば、以後は全コンテナで共有・永続されます。 - 既知のバグとして、defaultFeaturesの内容がプロジェクトの devcontainer-lock.json に混入する問題があります。lockfileをコミットしているリポジトリでは、個人設定が混ざっていないかcommit前に確認しましょう。
- Featureの
mounts内での${localEnv:HOME}置換は仕様上サポートされていますが、環境によって効かないという報告も過去にあるため、公開前に手元での動作確認をおすすめします。
まとめ
| やりたいこと | 方法 |
|---|---|
| 単一プロジェクトで永続化 |
devcontainer.json に mounts を書く(参考記事の方法) |
| 別プロジェクトにも展開 | 同じ mounts をコピー。target はコンテナユーザーのホームに合わせる |
| 全プロジェクトに自動適用 | 自作Feature(mounts + CLAUDE_CONFIG_DIR)を dev.containers.defaultFeatures に登録 |
「設定を書いたら中から検証する」を徹底すると安心してリビルドできるようになります。同じ構成を検討している方の参考になれば幸いです。
参考リンク
- devcontainerでClaude Codeの認証と会話履歴を永続化する(参考記事)
- Dev Container Features reference — containers.dev
- Developing inside a Container — VS Code Docs
- Add dev.containers.defaultMounts setting — microsoft/vscode #265651
- devcontainer-lock.json leaks default features — vscode-remote-release #11616
- anthropics/devcontainer-features