用 Claude Code 搭建安全可复现的开发环境
用 Claude Code 配好 Node、Docker、.env、权限、hooks 和可复现检查。
新电脑或刚 clone 的仓库,不应该让你花半天时间才能开始第一个有效修改。常见问题很固定:Node.js 版本不一致,npm 和 pnpm 混用,.env 过期,Docker volume 里残留旧 schema,本地步骤没有写进文档。Claude Code 可以加快这些工作,但前提是先把边界设好。
本文的目标不是让代理什么都自动做,而是建立一个可复现的开发环境:每个开发者、每次 Claude Code 会话,都读取同一套项目说明、使用同一个包管理器、遵守同一套机密信息规则,并运行同一组验证命令。
官方资料请以原文为准:Claude Code 安装、设置、权限 和 hooks。站内可以继续阅读 Claude Code 入门、CLAUDE.md 最佳实践 和 hooks 指南。
flowchart TD
A["检查本机工具"] --> B["固定 Node 和包管理器"]
B --> C["创建依赖和 .env.example"]
C --> D["把规则写入 CLAUDE.md"]
D --> E["用 settings.json 限制权限"]
E --> F["用 hooks 阻止危险命令"]
F --> G["运行 doctor、环境检查和测试"]
先定规则
把开发环境当成生产代码管理。重要规则要提交到仓库,真实密钥不要进入代理上下文,可能删除数据或发布代码的命令必须由人确认。
| 范围 | 文件或命令 | 作用 |
|---|---|---|
| 运行时 | .nvmrc、packageManager、Corepack | 避免 Node 和 pnpm 版本漂移 |
| 机密信息 | .env.example、.gitignore、permissions.deny | 防止真实凭据进入 prompt 或 commit |
| 项目记忆 | CLAUDE.md | 让 Claude Code 每次会话读取同一套规则 |
| 权限 | .claude/settings.json | 控制读取、Bash 和默认模式 |
| hooks | .claude/hooks/* | 在工具执行前做确定性拦截 |
| 验证 | doctor、check:env、test | 用命令结果替代感觉 |
可复制的初始化脚本
这个脚本适用于 Git Bash、WSL、macOS 或 Linux。它会创建一个最小 TypeScript 项目,校验环境变量,固定 pnpm,禁止读取秘密文件,并加入 PreToolUse hook。
#!/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"; exit 1; }
command -v claude >/dev/null || { echo "缺少 Claude Code CLI"; exit 1; }
corepack enable
corepack prepare pnpm@9.15.4 --activate
cat > package.json <<'JSON'
{
"name": "claude-dev-lab",
"private": true,
"type": "module",
"packageManager": "pnpm@9.15.4",
"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'
# 项目说明
## 环境搭建
- 使用 `.nvmrc` 指定的 Node 版本。
- 通过 Corepack 使用 pnpm,不要切换到 npm 或 yarn。
- 本地把 `.env.example` 复制为 `.env`,真实值由人手动填写。
- 不要读取、打印或提交 `.env` 和秘密文件。
- 修改代码前运行 `pnpm run doctor` 和 `pnpm run check:env`。
- 修改代码后运行最小相关测试,并记录结果。
## 工作规则
- 先探索,再给出简短计划。
- 没有人明确批准时,不运行破坏性命令或部署命令。
- 把 setup 变化保存在可复现文件中,不只留在终端历史里。
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 ?? "");
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
如果使用 Windows 原生环境,先确认工具链:
winget install Anthropic.ClaudeCode
claude --version
claude doctor
node --version
corepack enable
pnpm --version
如果 pnpm --version 失败,先修复 Node 和 Corepack。若 claude doctor 报代理、证书或登录错误,把原始错误保存下来,再让 Claude Code 在这个限制下分析原因。
更安全的提示词
claude -p "
请审计并补齐这个仓库的开发环境设置。
规则:
- 不要读取 .env、.env.* 或 secrets/ 下的文件
- 遵守 packageManager,不要把 pnpm 换成 npm 或 yarn
- 不要删除 Docker volume,也不要执行 git push
允许:
- 读取 README、package.json、CLAUDE.md 和 .claude/settings.json
- 执行 pnpm install、pnpm run doctor、pnpm run check:env 和 pnpm test
最后返回简短记录:执行的命令、修改的文件、发现的失败、仍需人工处理的步骤。
"
具体用例
| 用例 | 如何使用 |
|---|---|
| 新 SaaS 原型 | 加入 PostgreSQL 和 Redis 的 Docker Compose,从第一天保持可复现 |
| 团队仓库入门 | 让 Claude Code 读取文档、执行允许的检查,并补齐 onboarding |
| 内容站或产品页 | 保护 CTA、统计事件、OGP 和 AdSense 敏感页面 |
| 内部工具 | 标准化数据库 seed、队列、mock 和测试命令 |
Docker 项目可继续看 Docker Compose。团队协作可读 Claude Code 团队协作。CI 可以接上 CI/CD 设置。
常见失败
不要混用包管理器。如果仓库有 pnpm-lock.yaml,就不要让代理运行 npm install。把规则写进 CLAUDE.md,并在 package.json 保留 packageManager。
不要让 Claude Code 读取 .env。可审查的是 .env.example,真实值只留在本机。.gitignore 和 permissions.deny 要一起使用。
Docker volume 也很容易误导。旧 volume 可能让正确的迁移看起来失败。任何删除前,都要求 Claude Code 说明目标、风险和替代方案。
不要在主机上随便使用 bypassPermissions。它只适合隔离容器或虚拟机。来自不可信仓库的 hooks 也要在启动 Claude Code 前先人工阅读。
可复现检查清单
claude --version和claude doctor通过- 存在
.nvmrc或.node-version package.json包含packageManager- 只有一种 lockfile
.env.example最新,.env被忽略CLAUDE.md写明 setup、禁止事项和检查命令.claude/settings.json阻止秘密读取、git push和破坏性命令- 最终记录包含命令和结果
CTA 与验证结果
本地环境不稳,会影响购买链接、表单、统计事件和广告页面。想把这套流程做成可重复系统,可以从免费速查表开始,再看产品模板;团队落地可看培训与导入。
我按本文流程创建了最小项目,安装依赖,复制 .env.example,然后依次运行 pnpm run doctor、pnpm run check:env 和 pnpm test。最有价值的保护是禁止读取 .env,以及用 hook 阻止 git push 和破坏性命令。Masa 的实际经验是,环境搭建失败通常不是命令太难,而是前提没有写下来。
免费 PDF: Claude Code 速查表
输入邮箱即可获取一页 PDF,整理常用命令、审查习惯和安全工作流。
我们会妥善保护你的信息,不发送垃圾邮件。
把 Claude Code 变成真正能带来结果的工作流
先领取中文说明的免费 PDF,再进入英文商品页选择合适的教材。如果你需要团队落地、流程设计或内容变现支持,也可以直接咨询。
关于作者
Masa
专注 Claude Code 实务流程、团队导入和内容转化的工程师。
相关文章
从Obsidian到CLAUDE.md的Claude Code流程:不再反复解释上下文
把 Obsidian 工作笔记整理成 CLAUDE.md 运行说明,让 Claude Code 每次都带着正确上下文开始。
Claude Code 收入 CTA 路由:从文章分流到 PDF、Gumroad 与咨询
用 Claude Code 按读者意图把文章流量分到免费 PDF、Gumroad 教材或咨询入口。
Claude Code 团队交接规则: 把审查证据、权限、回滚和收入路径一起交付
面向团队的 Claude Code 交接格式: 证据、权限、回滚、免费 PDF、Gumroad 与咨询路径都要可审查。