让 AI 编程助手跑得起项目:Dev Container 实践记录

这周我把一个前后端项目整理成了适合 AI 编程助手执行任务的开发环境。

起因很简单:我让它补一组单测、修几个 lint,再顺手跑一下 E2E。代码没改几行,环境先炸了一串。

bash 复制代码
npm test
# node version mismatch

npx playwright test
# browser dependencies missing

docker compose up -d
# api waits for postgres, but postgres is not healthy

这类失败很微妙。人能靠经验绕过去,AI 只能按仓库里的命令执行。最后我意识到,问题不是"AI 会不会写代码",而是项目环境没有写给机器看。

下面是我最后保留下来的配置。

1. 先把运行时固定住

我先建 .devcontainer/devcontainer.json

json 复制代码
{
  "name": "ai-ready-dev",
  "build": {
    "dockerfile": "Dockerfile"
  },
  "forwardPorts": [3000],
  "postCreateCommand": "npm ci",
  "remoteEnv": {
    "NODE_ENV": "development"
  }
}

对应 Dockerfile:

dockerfile 复制代码
FROM docker.1ms.run/node:22-alpine

RUN apk add --no-cache \
  bash \
  curl \
  git \
  python3 \
  make \
  g++ \
  libc6-compat

WORKDIR /workspace

这一步先解决 Node 版本和 native module 构建问题。以前 README 里写"建议 Node 22",但只要某个人本机还停在 Node 18,AI 执行测试时就可能拿到完全不同的结果。

2. Compose 只管开发依赖

项目依赖 API、Postgres、Redis。以前经常是"数据库已经在本机后台跑着",但这种状态不能假设给 AI。

我把开发依赖写成 compose.dev.yaml

yaml 复制代码
services:
  app:
    image: docker.1ms.run/node:22-alpine
    working_dir: /workspace
    volumes:
      - .:/workspace
    command: sh -c "npm ci && npm run dev"
    ports:
      - "3000:3000"
    env_file:
      - .env.example
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy

  postgres:
    image: docker.1ms.run/postgres:16
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: app
      POSTGRES_DB: app
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app"]
      interval: 5s
      timeout: 3s
      retries: 20

  redis:
    image: docker.1ms.run/redis:7
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 20

这里有两个取舍:

  1. 这不是生产编排,只服务本地开发、AI 任务和 CI 复现。
  2. depends_on 只能帮你等到服务 healthy,业务层连接重试仍然要保留。

3. 把任务入口固定成命令

我之前给 AI 的指令太口语化,比如"跑一下测试看看"。这会让它自己猜命令,猜错了日志就乱。

后来我把入口收敛成固定脚本:

json 复制代码
{
  "scripts": {
    "dev": "vite --host 0.0.0.0",
    "lint": "eslint .",
    "test": "vitest run",
    "test:e2e": "playwright test",
    "db:migrate": "prisma migrate deploy",
    "db:seed": "node scripts/seed.js"
  }
}

然后每次任务前先让它跑:

bash 复制代码
docker compose -f compose.dev.yaml pull
docker compose -f compose.dev.yaml up -d
npm run lint
npm test

这样失败时就很好分层:是镜像拉不下来、依赖装不上、服务没 ready,还是测试真的没过。

4. Playwright 单独处理

E2E 测试是另一个常见坑。本机能跑,不代表容器里能跑。

我会在文档里明确两件事:

bash 复制代码
npx playwright install --with-deps
npm run test:e2e

如果团队 E2E 很重,更适合单独准备浏览器测试镜像。不要让 AI 每次临时摸索浏览器依赖。

5. 镜像预检提前做

我把镜像预检放在任务开始前:

bash 复制代码
docker pull docker.1ms.run/node:22-alpine
docker pull docker.1ms.run/postgres:16
docker pull docker.1ms.run/redis:7
docker pull docker.1ms.run/python:3.12-slim

毫秒镜像在这里只解决一件事:让开发容器和依赖服务镜像更稳定地拉下来。它不是 AI 工具,也不会帮你判断业务逻辑对不对。

这个边界很重要。镜像预检只是把环境噪音提前排掉,让 AI 真正开始处理代码任务。

6. 最后保留的检查表

检查项 判断标准
镜像 tag 不用 latest 跑团队环境
Dev Container 固定语言版本和系统依赖
Compose 固定 Postgres、Redis 等依赖服务
healthcheck 服务状态可被命令判断
.env.example 新环境变量完整
test/lint 一条命令可执行
migrate/seed 数据库初始化不靠口头提醒
E2E 浏览器依赖不靠本机
日志 能区分环境问题和业务问题

7. 复盘

AI 编程助手已经不只是补全代码了。它会在仓库里跑命令、读日志、改文件、再根据结果继续修。

项目环境越靠人记忆,它越容易表现得"不好用"。项目环境越能被配置、命令和日志表达,它越能像一个真正能接小任务的协作者。

这次改完后,我最大的感受是:不要先问 AI 能不能改复杂业务,先问它能不能稳定跑起项目。

相关推荐
腾讯云开发者2 小时前
港科大郭毅可谈Agentic AI时代的核心命题:人机共生,人不可能退场
人工智能
常丛丛2 小时前
5.6 LangGraph-Edges理解-Agent图的道路系统
人工智能
雪隐2 小时前
个人电脑玩AI-08让5060 Ti给你打工——我拿 Unlimited-OCR扫了 600 页书,然后悟了
人工智能·后端
Coffeeee2 小时前
Prompt要花心思写,与 AI 对话的七个技巧
人工智能·aigc·ai编程
蝎子莱莱爱打怪3 小时前
Claude Code 官宣新升级:子智能体默认后台跑,你边聊它边干活
人工智能
武子康3 小时前
调查研究-206 DeepSeek DSpark 深度解析:大模型推理加速,正在从“模型能力”转向“系统工程”
人工智能·agent·deepseek
甲维斯3 小时前
最佳work模型sonnet5来了,直接就能用!
人工智能
IT_陈寒4 小时前
React hooks 闭包陷阱把我的状态吃掉了,原来问题出在这里
前端·人工智能·后端