Claude Codeに環境構築を任せて事故らない:再現できる開発環境の作り方
「環境セットアップして」だけだと.envまで読まれる。Claude Codeに任せる範囲を権限・hooks・CLAUDE.mdで先に固める、再現可能な手順を実例で。
「このリポジトリの開発環境、セットアップしといて」
そう頼んで席を立ち、戻ってきたら、Claude Codeが .env の中身をターミナルに親切に表示してくれていました。本番DBのパスワードごと。誰も見ていないログだったのが救いです。
賢いんですよ、彼は。頼んだことはちゃんとやる。問題は、僕が「やっていい範囲」を先に決めていなかったことでした。
環境構築をAIに任せるときの落とし穴は、速さじゃなくてここなんです。今日は、Claude Codeに環境セットアップを任せても事故らない作り方を、僕が実際に踏んだ地雷込みで書きます。
この記事の要点
- 環境構築でAIに任せると速いが、「何を読ませ、何を禁止するか」を先に決めないと
.env流出や依存関係の二重化が起きる - 守りの順番は固定:
.nvmrc/packageManager→.env.example/.gitignore→CLAUDE.md→.claude/settings.jsonの権限 → hooksで危険コマンドを機械的にブロック .envは「AIに作らせる」のではなく「人間が手で編集する」ファイル。permissions.denyと.gitignoreの両方で守る- 仕上げは
doctor/check:env/testの3コマンドで検証。「できた気がする」で終わらせない - 本記事のbashスクリプトをそのまま走らせれば、安全な境界つきの最小プロジェクトが1分で立ち上がる
なぜ「セットアップして」の一言が危ないのか
Claude Codeは、ターミナルの中でファイルを読み、コマンドを実行し、必要なら編集します。ここが強さであり、こわさです。
新しいPCを買った日や、知らないリポジトリに初めて入る日を思い出してください。Node.jsのバージョンが合わない、npm と pnpm が混ざる、.env が古い、Dockerのボリュームに前のデータが残っている。この消耗をAIに肩代わりさせたい気持ち、痛いほどわかります。
でも「いい感じにセットアップして」と丸投げすると、AIは作業ディレクトリの中にある秘密情報も、壊しやすい設定も、全部「材料」として見にいきます。悪気はありません。範囲を教えていないだけです。
だから僕は、速さを取りにいく前に再現性を取りにいくことにしました。誰が実行しても同じ依存関係・同じ権限・同じ検証コマンドに着地する状態。これさえ作れば、AIは「便利だけど不安な自動化ツール」から「あとから監査できる共同作業者」に変わります。
先に決めておく守りの順番
実務で安定したのは、次の順番でガードを置くやり方でした。上から順に固めると、後の工程が崩れにくくなります。
| 項目 | 固定するもの | 理由 |
|---|---|---|
| 実行環境 | .nvmrc、packageManager、corepack | Nodeやpnpmの差で依存関係がずれないようにする |
| 機密情報 | .env.example、.gitignore、permissions.deny | APIキーや本番DBのURLを読ませない・コミットしない |
| 作業手順 | CLAUDE.md | 参加者が変わっても同じ手順をClaude Codeが読める |
| 権限 | .claude/settings.json | 危険なBash、.envの読み取り、git pushを制御する |
| 自動チェック | hooks | LLMの判断に任せず、危険コマンドを機械的に止める |
| 検証 | doctor、check:env、test | 「できた気がする」で終わらせない |
ここで一つだけ言葉を補足します。hook(フック)は「AIの足場(harness)の中で、決めたタイミングに必ず走る小さな処理」だと思ってください。Claude Codeへのお願い文ではありません。設定ファイルとスクリプトで強制的に動く、機械のガードレールです。お願いは破られますが、ガードレールは破られません。この違いが効きます。
足場そのものの考え方は、別記事のAIに仕事を任せる“足場”の作り方でも掘り下げています。先に流れをつかみたいならCLAUDE.mdベストプラクティスも合わせてどうぞ。
コピペで作る、安全な最小セットアップ
説明より動かすのが早いです。次のスクリプトは、Git Bash・WSL・macOS・Linuxで動く前提です。claude コマンド、Node.js、Corepack、pnpmの状態を確認し、検証できる最小プロジェクトを丸ごと作ります。Windowsネイティブだけで作業する場合は、Git for Windowsを入れるか、同じファイルをPowerShellで手作業作成してください。
#!/usr/bin/env bash
set -euo pipefail
APP_DIR="${1:-claude-dev-lab}"
mkdir -p "$APP_DIR"
cd "$APP_DIR"
# まず前提ツールがあるか確認。無ければ即終了する
command -v node >/dev/null || { echo "Node.js is required"; exit 1; }
command -v claude >/dev/null || { echo "Claude Code CLI is required"; exit 1; }
corepack enable
corepack prepare [email protected] --activate
cat > package.json <<'JSON'
{
"name": "claude-dev-lab",
"private": true,
"type": "module",
"packageManager": "[email protected]",
"scripts": {
"doctor": "node --version && pnpm --version && claude --version",
"check:env": "tsx src/env.ts",
"test": "vitest run --passWithNoTests"
},
"dependencies": {
"dotenv": "latest",
"zod": "latest"
},
"devDependencies": {
"@types/node": "latest",
"tsx": "latest",
"typescript": "latest",
"vitest": "latest"
}
}
JSON
mkdir -p src .claude/hooks .vscode
printf "22\n" > .nvmrc
cat > .gitignore <<'EOF'
node_modules
.env
.env.*
!.env.example
dist
coverage
EOF
cat > .env.example <<'EOF'
NODE_ENV=development
DATABASE_URL=postgresql://app:app@localhost:5432/app
REDIS_URL=redis://localhost:6379
EOF
cat > src/env.ts <<'TS'
import { config } from "dotenv";
import { z } from "zod";
config();
// 環境変数を型で検証する。足りなければ起動を止める
const Env = z.object({
NODE_ENV: z.enum(["development", "test", "production"]).default("development"),
DATABASE_URL: z.string().url(),
REDIS_URL: z.string().url().optional()
});
const parsed = Env.safeParse(process.env);
if (!parsed.success) {
console.error(parsed.error.flatten().fieldErrors);
process.exit(1);
}
console.log("env ok", {
nodeEnv: parsed.data.NODE_ENV,
hasRedis: Boolean(parsed.data.REDIS_URL)
});
TS
cat > CLAUDE.md <<'EOF'
# Project Instructions
## Environment Setup
- Use Node from `.nvmrc`.
- Use pnpm through Corepack. Do not switch to npm or yarn.
- Copy `.env.example` to `.env` locally, then edit values by hand.
- Never read, print, or commit `.env` or secret files.
- Before changing code, run `pnpm run doctor` and `pnpm run check:env`.
- After changing code, run the narrowest relevant test and record the command result.
## Work Rules
- Start with exploration and a short plan.
- Do not run destructive commands or deploy commands without explicit human approval.
- Keep setup changes reproducible in committed files, not in local terminal history.
EOF
cat > .claude/hooks/block-dangerous.mjs <<'JS'
import { readFileSync } from "node:fs";
const input = JSON.parse(readFileSync(0, "utf8") || "{}");
const command = String(input.tool_input?.command ?? "");
// この4パターンに当たったコマンドは、人間が確認するまで止める
const blockedPatterns = [
/rm\s+-rf\s+(\/|~|\$HOME)/,
/git\s+push\b/,
/curl\b.+\|\s*(bash|sh)/,
/Invoke-WebRequest\b.+\|\s*iex/i
];
if (blockedPatterns.some((pattern) => pattern.test(command))) {
console.log(JSON.stringify({
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: "危険なコマンドです。人間が目的と対象を確認してから実行してください。"
}
}));
} else {
console.log("{}");
}
JS
cat > .claude/settings.json <<'JSON'
{
"defaultMode": "plan",
"permissions": {
"allow": [
"Read",
"Bash(pnpm install)",
"Bash(pnpm run *)",
"Bash(git status *)",
"Bash(claude --version)",
"Bash(claude doctor)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"Bash(git push *)",
"Bash(rm -rf *)"
]
},
"env": {
"CLAUDE_CODE_SUBPROCESS_ENV_SCRUB": "1"
},
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "node .claude/hooks/block-dangerous.mjs"
}
]
}
]
}
}
JSON
pnpm install
cp .env.example .env
pnpm run doctor
pnpm run check:env
pnpm test
このスクリプトの狙いは「すぐ実装に入ること」ではありません。Claude Codeが安全に動ける境界を、コードを書く前に作ることです。defaultMode を plan にしておくと、最初は読み取りと調査が中心になり、いきなり書き換えられる心配が減ります。編集を任せる段階で、必要なコマンドだけ allow に足していけばいい。
Windowsネイティブで作業するなら、まずはこの確認から入ります。
winget install Anthropic.ClaudeCode
claude --version
claude doctor
node --version
corepack enable
pnpm --version
pnpm --version が通らないときは、Nodeのインストール → Corepackの有効化 → 端末の再起動、の順に潰してください。会社PCだとプロキシや社内証明書で落ちることもあります。その場合はエラーメッセージを丸ごと保存して、Claude Codeに「この制約の中で原因候補を整理して」と頼むのが早いです。
Claude Codeに環境構築を任せる依頼文
任せるときは、作業範囲・禁止事項・検証条件を一つの依頼にまとめて渡します。ここをサボると、AIは良かれと思って範囲を広げます。
claude -p "
このリポジトリの開発環境セットアップを点検してください。
守ること:
- .env、.env.*、secrets配下は読まない
- npmやyarnに切り替えず、packageManagerに従う
- 破壊的なDocker volume削除やgit pushは提案だけにする
実行してよいこと:
- README、package.json、CLAUDE.md、.claude/settings.jsonを読む
- pnpm install、pnpm run doctor、pnpm run check:env、pnpm testを実行する
最後に、実行したコマンド、失敗した点、修正したファイル、残る手作業を箇条書きで報告してください。
"
この形にしておくと、Claude Codeが勝手に「便利そうなこと」へ手を伸ばしにくくなります。とくに .env は、値を作るファイルではなく、ローカルで人間が編集するファイルです。Claude Codeには .env.example の不足を見つけさせるだけにして、実値は読ませない。この線引きを依頼文と権限の両方に書くのがコツです。
効く場面を3つ
1. 新規SaaSのプロトタイプ
Next.js・API・DB・テストを最初から組む場合は、上の最小セットにDocker Composeを足します。PostgreSQLやRedisをコンテナ化すると、僕が個人開発でよく踏んだ「自分のPCでは動くのに、別PCではDB接続だけ落ちる」問題がぐっと減ります。詳しい構成はClaude Code × Docker Composeガイドが参考になります。
2. 既存リポジトリへのオンボーディング
チームに入った初日は、実装の前に README・package.json・CLAUDE.md・CI設定をClaude Codeに読ませ、セットアップ手順の抜けを洗い出します。ここで「実行したコマンドの証拠」を残させると、そのまま次の参加者向けの手順更新に使えます。チーム運用の続きはClaude Codeチーム開発ガイドへ。
3. コンテンツサイトや収益導線の保守
ブログ・LP・商品ページでは、環境の不安定さがそのまま収益導線の事故につながります。CTAリンク、計測イベント、OGP画像、広告の表示確認をチェックリストに入れ、Claude Codeに「本文だけでなく収益導線を壊していないか」を確認させます。本文を直したつもりが計測タグを巻き込んでいた、というのは僕が実際にやった失敗です。
僕がやらかした失敗と落とし穴
正直に書きます。最初は地雷を踏みまくりました。
一番多かったのが、パッケージマネージャの混在です。pnpm-lock.yaml があるのに、つい npm install を走らせる。すると依存関係とlockfileが二重化して、原因不明の挙動差に何時間も溶かしました。packageManager を置いて、CLAUDE.md に「npmへ切り替えない」と明記してからは起きていません。
次にこわかったのが、冒頭の .env 流出です。「設定を見て」と頼むと、広い検索で .env に触れにいきます。permissions.deny と .gitignore を両方使い、レビュー対象は .env.example だけにする。公式の設定でも、機密ファイルはdenyで除外する方針が示されています。
Dockerのボリュームも落とし穴でした。古いスキーマが残っていると、マイグレーションを直しても挙動が変わらない。ただし docker volume rm はデータを消す操作です。だからClaude Codeには「削除コマンドを実行して」ではなく「削除が必要か判断して、実行前に理由と対象を出して」と頼みます。
bypassPermissions は、隔離されたコンテナやVM以外では使いません。速く見えますが、.git・設定ファイル・IDE設定・デプロイ関連まで一気に書き換わる危険があります。普段は plan か default で始め、安全だと確認できたコマンドだけ後から格上げする。この順番を守るだけで事故は激減します。
hooksにも一つ注意を。hookは自動で走るので、信頼できないリポジトリの .claude/settings.json をそのまま信用しないでください。clone直後は、Claude Codeを起動する前に .claude 配下を人間の目で確認するのが安全です。
再現性チェックリスト
公開前・共有前に、この9項目を上から確認します。
claude --versionとclaude doctorが通る.nvmrcまたは.node-versionがあるpackageManagerがpackage.jsonにある- lockfileが1種類だけ存在する
.env.exampleが最新で、.envはgitignoreされているCLAUDE.mdにセットアップ手順・禁止事項・検証コマンドがある.claude/settings.jsonで.env・secrets・git push・破壊的コマンドを制御している- hooksの中身を人間が読める場所に置いている
pnpm run doctor・pnpm run check:env・pnpm testの結果を最後に記録している
よくある質問
Q. .env を絶対に読ませない一番確実な方法は?
permissions.deny に Read(./.env) と Read(./.env.*) を入れ、さらに .gitignore でコミットも止めます。権限とgitの両方で塞ぐのがポイントです。レビューさせるのは .env.example だけにします。
Q. hooksと permissions.deny は何が違うんですか?
permissions.deny は「このツール・このパスは触らせない」という静的な禁止リストです。hooksは実行直前にスクリプトが走り、コマンドの中身を見て動的に止められます。rm -rf / のような中身まで見たい判定はhooks、ファイルやコマンド単位の禁止はdeny、と使い分けます。
Q. defaultMode は plan と default どっちで始めるべき?
知らないリポジトリや初回は plan です。読み取りと調査が中心になり、いきなり書き換えられません。中身を把握して安全だと確認できたら default に上げます。bypassPermissions は隔離環境以外で使わないでください。
Q. Windowsネイティブだとこのbashスクリプトはそのままだと動かない?
そのままでは動きません。Git for WindowsやWSLを入れてGit Bash上で走らせるか、同じファイル群をPowerShellで手作業作成してください。claude 自体のインストール確認は記事中のPowerShellブロックを使えます。
Q. チームに配るとき、設定はどこまで共有すればいい?
.nvmrc・packageManager・.env.example・CLAUDE.md・.claude/settings.json・hooksをリポジトリにコミットして共有します。逆に .env の実値だけは各自がローカルで手入力。手順を「ローカルのターミナル履歴」ではなく「コミットされたファイル」に残すのが再現性の肝です。
実際に試した結果
冒頭の .env 表示事件以来、僕は「AIを信用するか」で悩むのをやめました。代わりに見るのは、どのガードで止まったかです。
最小プロジェクトで試したところ、pnpm install → pnpm run doctor → pnpm run check:env → pnpm test まで、誰がやっても同じ順番で着地しました。とくに効いたのは2つ。.env を読ませない権限設定と、git push や破壊的コマンドをhookで止める部分です。これを入れてから、夜中の「あれ、本番に何か起きてないよな」という冷や汗が消えました。
実運用で痛感したのは、環境構築の失敗の多くが「コマンドを知らない」ではなく「前提が記録されていない」ことから来る、という事実です。だから次からは、セットアップそのものを記事やテンプレートと同じ品質で管理します。Claude Codeは、境界さえ先に引いてやれば、ちゃんと監査できる共同作業者になってくれます。
公式の一次情報は、インストールと認証がClaude Code setup、権限まわりがConfigure permissionsです。設定で迷ったらまずここを当たってください。
実務向けのテンプレートは商品一覧に、チーム導入の相談は研修・導入相談にまとめています。自分の手元でガードを一つ足すところから、ぜひ試してみてください。
無料PDF: Claude Code はじめてのチートシート
まずは無料PDFで基本コマンドと最初の使い方をまとめて確認してください。登録後はそのままテンプレート集や導入相談にも進めます。
スパムは送りません。登録情報は厳重に管理します。
Claude Codeを仕事で使える形にしませんか?
まず無料PDFで基本を固め、繰り返し使う作業はGumroad教材へ、チーム導入や権限設計は導入相談へ進めます。
この記事を書いた人
Masa
Claude Codeの実務活用、導入設計、収益導線改善を検証しているエンジニア。10言語の技術メディアを運営中。
関連書籍・参考図書
この記事のテーマに関連する書籍を楽天ブックスで探せます。
※ 当サイトは楽天市場のアフィリエイトプログラムに参加しています。上記リンクから商品をご購入いただくと、運営者に紹介料が支払われる場合があります。
関連記事
制作会社がClaude Codeに触らせる前に決める権限チェックリスト
クライアントサイトを壊さずにAI編集を使うための、制作会社向け権限と確認の型です。
SaaSサポートのバグ報告をClaude Codeで再現手順に変える実務フロー
問い合わせ文をそのまま開発へ投げず、再現手順、証拠、次の一手に整えるサポート向け手順です。
Obsidianの古いメモをClaude Codeの指示書に変える10分ルーチン
Obsidianに溜めたメモが毎回ゴミになる人へ。事実・決定・未確認に仕分けして、Claude Codeがそのまま動ける指示書に変える朝の10分の型を紹介します。