以下の内容はhttps://www.rasukarusan.com/entry/2026/03/16/190349より取得しました。


Claude Code on the Webのサンドボックスで開発環境を動かすためにやったこと全部

はじめに

最近、Claude Code on the Webを使って個人プロジェクトの開発をしている。Claude Codeは便利だ。コードを書いてくれるし、テストも回してくれる。ただ、こいつが動いているサンドボックス環境はセキュリティがしっかりしている分、「普通に開発環境立ち上げるだけ」にちょっと工夫がいる。

自分のプロジェクト(kidoku)はNext.js + NestJS + MySQL + MeiliSearchという構成で、ローカルではdocker-compose uppnpm run devで立ち上がる。これをサンドボックスで動かすまでにやったことを全部書いておく。

リポジトリは以下。

github.com

サンドボックス環境の制約

まず前提として、Claude Code on the Webのサンドボックスがどういう環境かを把握しておく。

  • カーネルがLinux 4.4.0(overlayfsに制限あり)
  • nftablesが使えない
  • Google Chromeがプリインストールされていない
  • ネットワークは「フルネットワーク」設定でも完全に自由ではない

最後のネットワークの話が地味に重要で、Claude Code on the Webの環境設定で「フルネットワーク」を選択していても、外部通信がブロックされるケースがある。具体的には外部DBホストへの接続や、特定のDockerイメージのdocker pullが通らないことがあった。「フルネットワーク」はあくまで主要なレジストリやAPIへのアクセスを許可するもので、完全に制限なしというわけではないっぽい。

この制約があるので、DBもMeiliSearchもすべてサンドボックス内のローカルコンテナとして立ち上げる構成にしている。外部サービスに依存しない、自己完結型の開発環境を作るのがポイント。

docker-composeが動かない → docker runで個別起動

最初にdocker-compose up -dを試したところ、overlayfsのoperation not permittedで止まった。docker-composeは内部的にoverlayfsを前提としているので、ここは素直に方針転換。

docker runで一つずつコンテナを立ち上げることにした。ポイントは3つ。

1. ストレージドライバをvfsにする

overlayfsの代わりにvfsを使う。パフォーマンスは落ちるが、開発用途なら問題ない。

sudo -E dockerd --iptables=false --bridge=none --storage-driver=vfs &

2. iptablesをlegacyモードにする

nftablesが使えないので、iptablesをlegacyモードに切り替える。これをやらないとDockerデーモンが起動しない。

sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy

3. --network=hostで起動する

ブリッジネットワークも使えないので、--network=hostで起動する。

docker run -d --name kidoku_db --network=host \
  -e MYSQL_ROOT_PASSWORD=root \
  -e MYSQL_DATABASE=kidoku \
  -e MYSQL_USER=dev \
  -e MYSQL_PASSWORD=pass \
  mariadb:lts

MySQLが使えない → MariaDBで代替

MySQL公式イメージはレイヤー展開時にコケる。Alpine系じゃないイメージは厳しいっぽい。

mariadb:ltsはAlpineベースで軽量なのでpullできた。MySQLとMariaDBはほぼ互換なので、Prismaからの接続もmysql://のままでいける。

DATABASE_URL="mysql://dev:pass@localhost:3306/kidoku"

docker-compose時代はdbというホスト名だったが、--network=hostなのでlocalhostに変わる。

MeiliSearchの日本語対応版

うちのプロジェクトでは日本語検索のためにMeiliSearchのプロトタイプビルド(getmeili/meilisearch:prototype-japanese-6)を使っている。これは特殊なイメージだが、問題なくpullできた。

docker run -d --name kidoku_meilisearch --network=host \
  -e MEILI_MASTER_KEY=masterKey \
  -e MEILI_NO_ANALYTICS=true \
  getmeili/meilisearch:prototype-japanese-6

Playwright MCPが動かない → v1.50.0を直接実行

Claude CodeにはPlaywright MCPとChrome DevTools MCPというブラウザ操作ツールが用意されている。ただ、サンドボックスではどちらも使えない。

  • Playwright MCP: 内部のPlaywrightバージョン(alpha版)とインストール済みChromiumのビルド番号が合わない
  • Chrome DevTools MCP: Google Chromeがインストールされていない

そこで、Playwright v1.50.0をバージョン固定でインストールし、スクリプトとして直接実行する方針にした。

npx playwright@1.50.0 install chromium

起動時にはサンドボックス対応のフラグを指定する。

const browser = await chromium.launch({
  args: [
    '--no-sandbox',
    '--disable-setuid-sandbox',
    '--disable-gpu',
    '--disable-dev-shm-usage',
    '--single-process',
    '--no-zygote'
  ]
});

--single-process--no-zygoteがこの環境では必須。これでフルページスクリーンショットもフォーム操作もいける。

Prismaのチェックサムエラー → 検証スキップ

Prismaクライアント生成時にエンジンのチェックサム検証で失敗することがある。環境変数一つで回避できる。

PRISMA_ENGINES_CHECKSUM_IGNORE_MISSING=1 pnpm --filter web prisma generate
PRISMA_ENGINES_CHECKSUM_IGNORE_MISSING=1 pnpm --filter api prisma generate

Google OAuthが使えない → 裏口ログイン

裏口ログイン機能を実装した。

本番環境ではGoogle OAuthを使っているが、サンドボックスでは外部ネットワーク制限でOAuthコールバックが通らない。

NextAuthのCredentialsProviderで裏口ログインを用意してある。ENABLE_BACKDOOR_LOGIN=trueで有効化。

# CSRFトークン取得
curl -s -c cookies.txt http://localhost:3000/api/auth/csrf

# ログイン
curl -X POST -b cookies.txt -c cookies.txt \
  http://localhost:3000/api/auth/callback/backdoor \
  -d "email=test@example.com&csrfToken=${TOKEN}"

全部自動化した

ここまでの手順を毎回やるのはしんどいので、SessionStartフックで全自動化した。

{
  "hooks": {
    "SessionStart": [{
      "type": "command",
      "command": "bash scripts/sandbox-setup.sh",
      "timeout": 300000
    }]
  }
}

sandbox-setup.shの処理フロー:

  1. サンドボックス環境かどうか判定(CLAUDE_CODE_REMOTE=true
  2. pnpm install
  3. iptablesをlegacyモードに切り替え
  4. Dockerデーモン起動(--storage-driver=vfs
  5. MariaDBコンテナ起動
  6. MeiliSearchコンテナ起動
  7. .envファイル生成
  8. prisma db pushでスキーマ反映
  9. prisma generateでクライアント生成
  10. シードデータ投入
  11. API・Webサーバー起動
  12. ヘルスチェック

これでClaude Codeのセッションが開始した時点でもう開発できる状態になっている。

ヘルスチェックも作った

全コンポーネントが正常に動いているか確認するスクリプトも用意した。

bash scripts/health-check.sh

チェック項目:

  • Dockerデーモンが動いているか
  • MariaDBが接続を受け付けるか
  • テーブルが存在するか
  • MeiliSearchが応答するか
  • APIがGraphQLクエリに応答するか(HMAC署名付き認証も検証)
  • Webサーバーが200を返すか

結果はPass/Fail/Warnで出る。何かコケてたら一発で分かる。

コマンド許可リスト

Claude Codeはセキュリティのためにコマンド実行時に許可を求めてくる。開発中に毎回聞かれるのはテンポが悪いので、.claude/settings.jsonに許可リストを書いておく。

{
  "permissions": {
    "allow": [
      "Bash(docker *)",
      "Bash(pnpm *)",
      "Bash(node *)",
      "Bash(npx playwright*)"
    ]
  }
}

50個くらい登録してあって、これでClaude Codeが自律的に動ける。

まとめ

サンドボックス環境で開発環境を動かすためにやったことの一覧。

問題 代替策
フルネットワークでも外部通信が通らない DB・検索エンジンをローカルコンテナで自己完結
docker-composeが動かない docker run --network=hostで個別起動
overlayfsが使えない --storage-driver=vfsでDockerデーモン起動
nftablesが使えない iptables-legacyモードに切り替え
MySQLイメージがpullできない MariaDBで代替
Playwright MCPが動かない Playwright v1.50.0を直接スクリプト実行
Chrome DevTools MCPが動かない 同上
Prismaチェックサムエラー PRISMA_ENGINES_CHECKSUM_IGNORE_MISSING=1
Google OAuthが使えない 裏口ログインで代替

「フルネットワーク」設定でも外部通信が完全に自由ではないという前提に立って、最初からローカル完結型で組んでおくのが結局一番安定する。Claude Code on the Webでガッツリ開発したい人の参考になれば。




以上の内容はhttps://www.rasukarusan.com/entry/2026/03/16/190349より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14