在你电脑上能跑,在我电脑上不行:vibe 项目的开发环境标准化实战
你的代码跑在三个互不相同的环境里:本机、新开的 agent 会话、CI。本文讲 vibe 项目的开发环境标准化:devcontainer.json 全模板(Node+Postgres 逐字段解释)、nix flakes 终极形态,以及 15 分钟最小可行版。

开篇先划界:这篇讲什么、不讲什么
站内已经有一篇讲 CI/CD 的指南(管"代码提交后怎么自动跑起来"),还有一篇讲自托管部署的(管"生产环境在哪跑")。这篇讲的是第三块拼图:开发环境——你的代码在被写出来的那一刻,跑在什么样的机器上。CI 管的是"提交之后",这篇管的是"提交之前",两者互补不重叠。
如果你是一人团队,可能会觉得"开发环境标准化"是大公司的矫情。但 vibe coding 时代,这个问题的受害者恰恰是一人开发者:你的"协作者"不是人,是每一次新开的 agent 会话——它没有你的机器记忆,每次都要重新猜你的环境长什么样。
"在我电脑上能跑",在 agent 时代有三层含义
经典笑话是"在我电脑上能跑,在你电脑上不行"。2026 年的版本是三份环境、三种人生:
第一份:你的本机。Node 20.11,全局装了 pnpm 9,系统里有三年前 brew 装的 libvips,.env.local 里躺着 40 个环境变量,其中 5 个已经过期但没人敢删。项目跑得好好的——因为所有坑都被你的肌肉记忆填平了。
第二份:新开的 agent 会话。Claude Code 新开一个会话,或者你把仓库丢给另一个 AI 工具,它开始装依赖。AI 不知道你全局的 Node 是 20 还是 22,不知道 sharp 需要系统级 libvips,于是它要么瞎装一通污染你的全局环境,要么在沙箱里装完、关掉会话就全丢了,下次重来一遍。更糟的是,它可能"修好"了环境——用一种跟你本机完全不一样的方式。
第三份:CI / 协作者的机器。CI 用 node:22-slim 镜像跑测试,挂了。协作者(如果有)clone 下来,npm install 报 gyp 错误。三个人三个结果,debug 的第一步永远是"先对齐环境",而不是看代码。
根因就四类,一一对应:1)运行时版本漂移(Node/Python 全局版本);2)系统级依赖(C++ 编译的原生模块、数据库客户端库);3)环境变量散落(.env 文件没进仓库、文档里没写);4)服务依赖(Postgres/Redis 在本机是 brew 起的,在 CI 是 service container,在 agent 会话里根本不存在)。AI 写代码快,但它不会替你管这四类东西——除非你把"环境"本身写成代码,扔进仓库。
devcontainer 分层架构图:编辑器、容器、features 与 compose 服务
图 1:三份环境、三种人生的根因对照——本机、agent 新会话、CI 的四类环境差异(运行时版本、系统依赖、环境变量、服务依赖)。
方案一:devcontainer,一键可复现的开发环境(推荐)
devcontainer 是 VS Code / Cursor / Windsurf 都支持的开放标准:一份 .devcontainer/devcontainer.json 描述"这个项目需要什么样的开发机器",编辑器自动起一个 Docker 容器,所有人在容器里开发。下面是一个 Node + Postgres 项目的完整模板,逐字段解释:
{
"name": "my-vibe-app",
"image": "mcr.microsoft.com/devcontainers/typescript-node:22",
// 运行时版本锁死:告别"我的是 20 你的是 22"
"features": {
"ghcr.io/devcontainers/features/node:1": { "version": "22" },
"ghcr.io/devcontainers/features/docker-in-docker:1": {}
},
// 系统级依赖:sharp 要的 libvips 这类,用 customizations 或 Dockerfile 预装
"customizations": {
"vscode": {
"extensions": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"]
// 编辑器插件也进版本:新会话自动装好,不用口头传授
}
},
"forwardPorts": [3000, 5555],
"portsAttributes": { "3000": { "label": "App", "onAutoForward": "notify" } },
// 服务依赖:Postgres 用 compose 一起起,数据卷持久化
"dockerComposeFile": ["../docker-compose.dev.yml"],
"service": "app",
"workspaceFolder": "/workspaces/my-vibe-app",
"postCreateCommand": "pnpm install",
// 环境变量:模板进仓库,真值走本地 .env(gitignored)+ 文档说明
"remoteEnv": { "DATABASE_URL": "postgresql://dev:dev@db:5432/myapp" }
}
配一份 docker-compose.dev.yml 把 Postgres/Redis 一起带起来,数据用 named volume 持久化,容器删了数据还在。关键点:postCreateCommand 让依赖安装自动化——agent 新开会话时,它面对的不再是"一台陌生的裸机",而是一个已经装好依赖、配好数据库的现成工作台。它不用猜 Node 版本,不用 brew 装东西,不会污染你的全局环境。
对 agent 友好的三个细节:1)在 README 顶部写一句"本项目用 devcontainer 开发,Cursor/VS Code 打开即会提示 Reopen in Container"——AI 读 README 后会自己照做;2)把 .env.example 写全,每个变量一行注释说明哪来(哪怕值是空的),AI 最怕的是"缺了变量但不知道缺哪个";3)系统依赖能用 features 装就不用 Dockerfile 手写,features 是官方维护的,AI 生成 Dockerfile 容易写出缓存失效的层。
方案二:nix flakes,声明式的终极形态(可选)
如果你连 Docker 都不想碰(比如项目要跑在非容器环境),nix flakes 是更彻底的方案:一份 flake.nix 声明"这个项目需要 Node 22.5.1、Postgres 16、ffmpeg 7",nix 保证任何机器上装出来 bit-for-bit 一致。它比 devcontainer 更轻(不需要容器运行时),但学习曲线陡,且 macOS 上有些坑。一人团队的建议:先用 devcontainer 跑起来,等你真的被"我连容器都不想装"折磨时再考虑 nix。不要为了时髦同时上两套。
方案三:最小可行版——三个文件先保命
如果 devcontainer 对你现阶段太重,至少做到这三件,每件 5 分钟:
1).nvmrc(或 .node-version)写死 Node 版本 + package.json 里 "packageManager": "pnpm@9.7.0" 锁死包管理器。AI 新会话第一件事就是读这两个文件,版本对齐 80% 的"跑不起来"就消失了。
2)docker-compose.dev.yml 只起有状态服务(Postgres/Redis/MinIO),应用本身还在本机跑。这是投入产出比最高的一步:服务依赖是环境问题里最难口头讲清的("你先 brew install postgresql@16,然后 initdb……"),容器化之后变成一条命令。
3).env.example 与 .env 的"影子同步":每次加新环境变量,先加到 .env.example 写注释,再填真值。给这个动作配一个 CI 检查(diff .env.example 的 key 集合与代码里读取的 key 集合),散落问题从此有哨兵。
让 CI 和开发环境同构:最后一公里
环境标准化的终点是:CI 跑测试用的环境 = 你开发用的环境。devcontainer 有一个官方 action(devcontainers/ci)可以直接在 CI 里用同一份 devcontainer.json 起环境跑测试。做不到完全同构时,退而求其次:CI 镜像的 Node 版本、系统依赖安装脚本,与 devcontainer 共用同一份 Dockerfile 或 features 列表——"同一份声明,两个地方用",漂移就无处藏身。
验收标准很简单,叫"新人(或新 agent)30 分钟测试":找一个完全没碰过这个项目的人——或者开一个全新的 agent 会话,只给它仓库地址和 README,看它 30 分钟内能不能把项目跑起来并跑通测试。跑不起来,说明环境知识还躺在你的脑子里,没进仓库。把这个测试每季度跑一次,环境腐烂就追不上你。
devcontainer 分层架构图:编辑器、容器、features 与 compose 服务
图 2:devcontainer 分层架构——编辑器经 devcontainer.json 拉起容器,features/插件/端口一次声明,Postgres 等服务由 compose 协同,agent 新会话开箱即用。
一人团队的 15 分钟落地清单
1. 加 .nvmrc + 锁 packageManager(5 分钟)。2. 写 docker-compose.dev.yml 起 Postgres/Redis(5 分钟)。3. 补全 .env.example 并加 key 集合的 CI 检查(5 分钟)。这三步做完,你已经消灭了 80% 的环境问题。4. 有余力再上 devcontainer.json 全套(30 分钟),把"开箱即用"变成默认体验。5. README 顶部加一句话说明环境怎么起,AI 和未来的你都会感谢现在的你。
一句话:AI 写代码的速度越快,"环境"这种慢变量就越是瓶颈。把环境写成代码进仓库,是你能给每一个未来的 agent 会话——以及三个月后的自己——最好的 onboarding 文档。
评论 (0)
相关文章

AI 写代码快,决策散落更快。本指南给一人团队引入 ADR(架构决策记录):一份真实五段式模板、'只记不可逆'原则(每月 2-3 篇)、让 AI 起草的 prompt、以及每季度复审与 superseded 考古层。

AI 生成的代码没有可靠性概念,一切都靠'感觉挺快'。本指南给一人团队补上 SRE 决策层:SLI/SLO/错误预算三概念一人版、两档烧蚀率告警、最小实现(一个 SQL + 一个 cron + 状态页一句话),以及'预算烧完就冻结发版'的纪律。

AI 生成的下单代码从不考虑并发:两个用户同时点购买,库存变负、余额被 double-spend。本篇从竞态三现场讲起,覆盖事务隔离级别选型、乐观锁(version 列)与悲观锁(SELECT FOR UPDATE)的取舍、幂等键防重放、热点写入的队列串行化,以及 Prisma / Drizzle 的事务实战代码,开箱即用的落地清单。