自宅NASにClaude Code専用サンドボックスを作った全記録|DXP2800 × Tailscale × Docker
更新日:2026年5月13日|カテゴリ:NAS応用
結論:自宅 NAS 上に Claude Code 専用サンドボックスを作ると、出張先からでも「フル権限の AI コーディング環境」を呼び出せます
私(yamakashi)は UGREEN DXP2800 という 2 ベイ NAS の上に、Tailscale VPN からしか到達できない Claude Code 専用の Docker サンドボックスを構築しました。出先のノート PC からも、自宅 Mac からも、スマホの Termius からも、同じコンテナに入って同じプロジェクトを編集できます。Claude Code は --dangerously-skip-permissions のフル権限で動かしますが、影響範囲はコンテナと NAS シェアフォルダ内に限定され、母艦の Windows / Mac を巻き込みません。本記事は全体俯瞰のメイン記事で、各論(Tailscale ACL の設計、Claude Desktop の SSH トラブル、フル権限運用ルールなど)は続く各記事に分けています。
1. なぜ自宅 PC ではなく NAS に Claude Code を置いたのか
もともと私は、自宅 Windows 11 デスクトップの WSL(Ubuntu)で claude --dangerously-skip-permissions を動かしていました。気持ちが揺らいだのは、出張中に「自宅でやりかけのリポジトリを少しだけ触りたい」と思った瞬間です。ノート PC にも同じ環境を作れば動きますが、プロジェクトファイルは自宅のデスクトップに置きっぱなし。コミット前の作業や検証用フォルダはそうそう持ち出せません。
もう 1 つ気になっていたのが、--dangerously-skip-permissions のリスクです。確認なしにファイル操作やコマンド実行が走るため、Web から拾ったサンプルコードを誤ってフル権限のセッションで実行すれば、母艦の WSL 環境を壊しかねません。母艦のファイルシステムから完全に切り離すほうが筋がいい、と感じていました。
私が「NAS にサンドボックスを置く」と決めた 3 つの理由
① 家でも出先でも同じ環境にアクセスしたい。
② フル権限 Claude Code の影響範囲を母艦 OS から切り離したい。
③ NAS は常時稼働しているので、開発サーバとして遊ばせない手はない。
VPS を借りる選択肢もありましたが、ソースコードと検証データを外部 VPS に常時置きたくない派なのと、月額コストとメンタルコストを下げたかったのが決め手でした。
2. 全体構成の俯瞰:Tailscale と Docker をどう組み合わせたか
先に完成形を言葉で書いておきます。クライアントから NAS のコンテナまで、データはこういう順で流れます。
[ Win11 PC / Mac / スマホ / 他PC ]
↓ Tailscale VPN(WireGuard、tag:client のデバイスだけ)
[ Tailscale Tailnet(100.x.x.x プライベートIP空間)]
↓
[ DXP2800 NAS ]
├─ ts-sandbox コンテナ(Tailscale 本体、ネット入口)
└─ claude-workspace コンテナ
└ network_mode: service:tailscale(独自NIC無し)
├─ /workspace ← /volume1/sandbox/projects(bind mount)
└─ Docker volume × 5(Claude設定 / gh / git / secrets / ssh)
2 つのコンテナを Docker Compose で動かしています。1 つは Tailscale 本体だけが入った軽量な ts-sandbox、もう 1 つは Claude Code・GitHub CLI・OpenSSH サーバ・ビルドツールを詰めた claude-workspace。両者を network_mode: "service:tailscale" でつなぎ、claude-workspace 側は独自のネットワークインターフェースを持たない構成にしています。
この設計の旨味は「LAN からの直接 SSH が物理的にできない」点です。普通に Docker でポートをマッピングする方式だと NAS の LAN IP に 22 番が開いて家の Wi-Fi 内から見つけられる余地が残りますが、Tailscale コンテナへの相乗り構成ならコンテナの 22 番は Tailnet 上の仮想 IP にしか露出しません。Tailscale を持っていないデバイスからは存在自体が見えない、という遮断層になります。
永続化も最初から意識しました。プロジェクト本体は NAS シェアフォルダ /volume1/sandbox/projects/ に置いてコンテナ内 /workspace/ に bind mount。コンテナを作り直しても作業ファイルは消えず、Windows のエクスプローラから SMB 経由で覗けます。Claude 設定、gh 認証、SSH 公開鍵、シークレットは Docker ボリュームに分けて、Windows から不用意に開けないよう区分けしました。
3. 主要な設計判断 5 つ
5 つの設計判断(要点)
① Tailscale はサブネットルーター化しない:NAS 全体ではなくコンテナだけを Tailnet に出すシンプル構成。権限が広がりすぎず、ファイアウォール設計の難易度が抑えられる。
② network_mode: "service:tailscale" で相乗り:claude-workspace に独自 NIC を持たせず、LAN にも Docker ブリッジにも顔を出さない。Tailscale 経由でないトラフィックは物理的に届かない。
③ アクセス制御は Tailscale ACL の tag ベース:tag:sandbox(NAS)と tag:client(手元クライアント)を定義し、「tag:client だけが tag:sandbox に SSH できる」とした。新しいクライアントは tag を付けるだけ。
④ outbound 通信はあえてフリー:npm install や pip install が普通に動かないと開発環境として成立しないため、外向き通信は絞らない。リスクは後述の運用ルールでカバーする。
⑤ SSH は Tailscale SSH ではなく OpenSSH + 公開鍵:Tailscale SSH は service:tailscale 構成だと claude-workspace 側のユーザーを解決できず failed to look up local user が出る。素直に OpenSSH を立てて、認証は公開鍵に任せた。
④ を選んだ時点で「フル権限の Claude Code が外部に何かを持ち出す経路が技術的にはある」状態になります。設計だけでは塞ぎきれないので、シークレット隔離・信頼境界・GitHub 二重化といった運用ルールでカバーする方針にしました(詳細は別記事)。
4. 構築プロセスのハイライト:うまくいった所
全手順を書くと相当な分量になるので、本記事では「うまくハマった」要点だけ抜粋します。コマンド全文は続く詳細記事に譲ります。
4-1. 「永続化すべきもの」を最初に紙へ書き出した
これが一番効きました。プロジェクト本体、Claude 設定、gh 認証、Git 設定、シークレット(パーミッション 700)、SSH 鍵、Tailscale ステート。書き始める前にメモアプリへ洗い出してから docker-compose.yml に落としたので、後の手戻りが小さく済みました。
4-2. Compose のコアは「相乗り」と「ヘルスチェック」
Compose で重要なのは 2 か所です。1 つは claude-workspace 側の network_mode: "service:tailscale"。もう 1 つは depends_on の condition: service_healthy と、tailscale 側の healthcheck(tailscale status をプローブにする)のセット。これがないと Tailscale のセッション確立前に sshd が起動して、再起動直後だけ SSH が拒否される症状に悩まされます。
4-3. ベースイメージは node:20-slim(UID 1000 重複に注意)
Claude Code は npm 配布なので node:20-slim が素直に使えます。ただしこのイメージには既に UID 1000 の node ユーザーがあるので、Dockerfile の冒頭で userdel -r node してから自分のユーザーを作っています。cc='claude --dangerously-skip-permissions' という短いエイリアスを ~/.bashrc に入れて、タイプ数節約と意識付けを兼ねさせている小ネタもあります。
4-4. Tailscale ACL は新しい grants 文法
Web 上の解説は古い acls 文法のものが多いのですが、私のテナントは新しい grants 文法が初期値でした。tagOwners で tag を登録し、grants で「tag:client から tag:sandbox へだけ通す」と書く形に落ち着いています。締め出し防止に「自分自身(admin)はどこにでも入れる」grants を 1 行入れておくのが、運用上の保険として効きました。
5. ハマって学んだ 3 エピソード
うまくいった話だけだと楽勝に見えるので、特に学びが大きかった 3 つを抜粋します。
5-1. Docker グループの「再ログイン忘れ」
UGOS Pro 上で Docker を入れた直後に docker compose up を叩くと permission denied while trying to connect to the Docker daemon socket が出ます。sudo usermod -aG docker $(whoami) は教科書通りですが、ログアウトと再ログインを挟まないと反映されないのがトラップでした。最初に docker ps を sudo なしで叩いてテストするのが、NAS Docker を触るときの私の鉄則になりました。
5-2. Tailscale ACL を書く前に Auth Key を発行した
Admin Console で Auth Key に tag:sandbox を付けたものの、ACL 側で tagOwners に登録していなかったため、コンテナ側で requested tags [tag:sandbox] are invalid or not permitted になり unhealthy になりました。正しい順序は「ACL を先に書く → Auth Key を発行 → コンテナを起動」。Tailscale 関連は「ACL ファースト」が時短のコツです。
5-3. Claude Desktop の Code タブからだけ SSH が通らない
最終盤で一番厄介だったのが、Claude Desktop からの SSH 接続です。PowerShell の ssh では問題なく繋がるのに、Code タブからだけ Permission denied (publickey) や「All configured authentication methods failed」が出る。原因は Windows 標準 OpenSSH(9.x)と Git for Windows 同梱の OpenSSH(10.x)が同じ ed25519 鍵を別解釈することでした。Claude Desktop は内部で Git 版を呼ぶようで、10.x はデフォルト形式の ed25519 鍵を passphrase 付きと誤判定するケースがあります。解決は ssh-keygen -t ed25519 -m PEM で PEM 形式の鍵を作り直すだけ。丸 2 日溶かしたので、切り分けから解決手順までを独立記事にまとめました。
関連記事:Claude Desktop の Code タブで Permission denied (publickey) が出る本当の原因と解決法 → https://arigatonas.com/claude-desktop-publickey-windows/
6. 完成した環境でできるようになった 4 つのこと
構築が終わってみると、当初の目論見以上に多くの経路から同じ環境に入れるようになりました。日常的に使っている 4 経路です。
① VS Code Remote-SSH:Windows 11 PC から
~/.ssh/config 記述で 1 クリック接続。拡張機能はリモート側に自動インストール、ターミナルもコンテナ内シェルに直結。Claude Code を cc で呼び、横で差分ビューを確認するワークフロー。② Termius(スマホ):Android / iOS に同じ設定を入れて、出先で進捗をちらっと確認。
tail -f や htop で挙動を見るだけでも心理的余裕が違う。③ Mac の標準 SSH:
~/.ssh/config を同じ書き方にするだけ。Mac 標準 OpenSSH は ed25519 鍵を素直に扱うので、設定即接続。④ Claude Desktop の Code タブ:保存済みの接続を選び、「フォルダを選択」で
/workspace/trusted/<プロジェクト名> を指定する 3 ステップ。フォルダ選択を省くと /home/yamakashi がカレントになり、シークレットの置き場所が見えるので、毎回明示するのが習慣化のコツ。
クライアントを増やすときも、Tailscale で tag:client を付けて公開鍵を authorized_keys に足すだけ。「コンテナ側は何も変えずにクライアントを増やせる」のは Tailscale + 公開鍵認証の恩恵が分かりやすく出る場面です。
7. 数週間運用してみての所感
2026 年 4 月から運用を始めて、執筆時点で数週間。使い心地と改善したい点を率直に書きます。
・出張先のホテルで普通に作業できる。回線が細くても SSH と Claude Code の応答はほぼ気にならない。
・母艦 PC の WSL を「サンドボックス兼用」から「実用環境専用」に戻せた。母艦が散らからない。
・コンテナを作り直すのが怖くない。ボリュームを残せば認証も SSH 鍵も消えない。
・NAS の電気代以外、追加コストがほぼゼロ。VPS を月額で借りない判断は自分には合っていた。
・大規模な npm ビルドや重い処理は DXP2800 の CPU だとさすがに遅い。
・Tailscale のキー期限切れに気づくのが遅れがち。来期は監視を入れたい。
・outbound フリーのままで運用を続けていいか、半年後にもう一度見直す予定(Exit Node や iptables ホワイトリスト案)。
・コンテナのバックアップを Borg や restic で自動化できていない。
意外だったのは、「自宅 LAN 内にいるときも、わざわざ Tailscale 経由で繋ぐ」習慣がついたことです。経路を 1 本に絞ると運用の頭の使い方がシンプルになり、入り口は常に dxp2800-sandbox-1。VPN を使い慣れていない方ほど、想像以上にメリットを感じる部分だと思います。
8. これから NAS で Claude Code をやってみたい方へ
始める前のチェックリスト
① NAS の Docker が「sudo なし」で動くか確認:id や getent group docker でグループ所属を見て、docker ps が sudo 抜きで通るところまで先に整える。NAS 製品ごとに差が出る部分。
② Tailscale は ACL ファースト・tag 思想で組み立てる:最初の 1 時間で tagOwners と最低限の grants を書く。後から「子供のタブレットからは入れないように」といった要望にも柔軟に対応できる。
③ 永続化すべきものを「先に紙に書く」:プロジェクト、Claude 設定、gh 認証、SSH 鍵、シークレット、Tailscale ステート。段取りに 30 分かけると「再ビルドで全部消えた」事故を避けられる。私は最初に SSH 鍵を漏らして、しばらく鍵登録をやり直す日々を送りました。
9. よくある質問(FAQ)
docker グループの扱いや /dev/net/tun の有無が異なるため、Tailscale コンテナ起動時の前提は機種ごとに確認が必要です。設計思想(2 コンテナ + service:tailscale + ACL)自体は移植性が高いと考えています。/workspace/trusted/ と /workspace/untrusted/ の区別、シークレットを ~/.secrets に隔離する手法を本構成では導入しています。詳細は別記事「フル権限 Claude Code を安全に運用する運用ルール(公開準備中)」で深掘りします。Anthropic 公式も --dangerously-skip-permissions はサンドボックス内のみでの利用を推奨しています(2026 年 5 月時点)。git push で二重化する運用ルールを組み込んでいます。シークレット類は暗号化したファイル単位で別の保管場所(パスワードマネージャや別ディスク)に置くと安心です。NAS の RAID は冗長性であってバックアップではない、というのは常に意識しています。claude-workspace コンテナで複数を併用しています。10. まとめ:NAS は Claude Code 専用サーバとして十分に化ける
・フル権限 Claude Code は、母艦 OS から切り離した NAS コンテナでやると気が楽
・Tailscale + Docker の 2 コンテナ構成(
network_mode: "service:tailscale")で、LAN 直アクセス不能の入口を作れる・アクセス制御は Tailscale ACL の tag ベース、認証は OpenSSH 公開鍵に任せる役割分担
・永続化リストは「先に紙に書く」。後付けは再ビルドのたびに痛い
・VS Code Remote-SSH / Termius / Mac / Claude Desktop の 4 経路から同じコンテナへ
・運用は「設計+習慣」の合わせ技。フォルダ指定やシークレット隔離が思った以上に効く
NAS は写真や動画の倉庫としての印象が強い機器ですが、Docker と VPN を組み合わせると「常時稼働の自宅開発サーバ」に化けます。本記事は全体俯瞰のメインで、ネットワーク設計、SSH トラブルシュート、永続化パターン、フル権限運用ルールといった各論は独立した記事に分けています。下の関連記事から、興味のある切り口で読み進めていただければと思います。
関連記事:Tailscale × Docker で NAS を公開しないリモート開発環境を作る方法(公開準備中)
関連記事:Claude Desktop の Code タブで Permission denied (publickey) が出る本当の原因と解決法 → https://arigatonas.com/claude-desktop-publickey-windows/
関連記事:Docker × OpenSSH で公開鍵を永続化する正しい設計(公開準備中)
関連記事:フル権限 Claude Code を安全に運用する 5 つの運用ルール(公開準備中)
