← 返回博客列表
工程实践2026-05-26·6 分钟阅读

通用部署描述符:为什么我们做了自己的 schema 而不是用 Heroku buildpacks

UniversalAppDescriptor — runtime / build / start / env / pre_deploy / health 6 字段。扫描器只猜默认值,AI 引导填空白,改写器和部署 agent 只看描述符。

Heroku buildpacks、Nixpacks、Railway 自动检测 — 都解决了"我有一段代码怎么跑起来"这个问题,但都解决得不够。问题在于:它们要么默认了一套自己的运行时基础设施(buildpacks 假设跑在 Heroku Dyno),要么尝试"自动猜一切"(Nixpacks 试图自动生成 Dockerfile),都没有给用户"看一眼能改"的空间。

我们做了 UniversalAppDescriptor — 一个 6 字段的 JSON / YAML schema,扫描器只填默认值,AI 引导帮你确认或改空白,改写器和部署 agent 只看描述符。任何栈、任何运行时,描述符就是中间语言。

6 个字段

schema_version: '1.0'
runtime: node                    # 大类:node/python/go/java/php/ruby/static/other
runtime_version: '20.0.0'        # 具体版本
build:
  install: npm install
  command: npm run build
start:
  command: npm start
  port: 3000
  health_path: /healthz
  health_expected_status: 200
env:
  required_keys: [DATABASE_URL, REDIS_URL]
  defaults:
    NODE_ENV: production
pre_deploy:                      # 数据库迁移等
  - command: npx prisma migrate deploy
    is_reversible: true
    timeout_sec: 300
gaps: []                         # 扫描器没填的字段 → AI 引导问用户

为什么是大类 runtime?

因为框架变化太快(2020 年 Next.js 没有 app router、2023 年突然有了)。但运行时变化慢 — Node.js 这个名字从 2010 用到 2026 还在。我们以"大类 runtime + 具体版本"为分层,框架细节扔给 build / start 字段,这样新框架出现时不用改我们的 schema。

扫描器只猜默认值

关键决策:扫描器对识别不确定的字段返 gaps,而不是瞎填。AI 引导拿 gaps 列表向用户问问题"你的健康检查路径是 / 还是 /api/health?",用户回答后写入描述符。

不替用户做决定,比替用户做对决定更重要 — 因为前者总是安全的,后者偶尔会错。

改写器看不到框架

改写器读描述符产部署产物(.env / pm2 ecosystem / systemd unit / nginx vhost),整个过程不知道你用的是 Next.js 还是 Nuxt 还是 SvelteKit。从描述符的视角它们都是「node runtime + npm start + port 3000」,改写器吐相同的产物。

演进:Tier 1 / Tier 2 分层

Tier 1 是高保真识别 — 我们对 Next.js / FastAPI / 微信小程序 / 静态站 4 个栈做了专门的描述符产出器,准确度 ~95%。Tier 2 是兜底 — 对任意 node/python/go 项目用启发式产最小可用描述符,准确度 ~70% 但保证产物。gaps 字段在 Tier 2 项目里会有更多内容,AI 引导填空。

用 Tier 1 你 30 秒部署,用 Tier 2 你可能花 5 分钟回答问题。但你永远不会被卡在「系统不支持你的栈」。

同类阅读

评论功能未启用(需要环境变量 NEXT_PUBLIC_UTTERANCES_REPO=owner/repo)