The Twelve-Factor App 由 Heroku 团队于 2011 年提出,是一套面向 SaaS / 云原生应用的方法论。它不是具体框架,而是一组设计约束,用来提高应用的可部署性、可扩展性与可运维性。以下按原典十二条说明要点。
I. Codebase — 一份代码库,多份部署
一个应用对应一个版本库;不同环境(dev / staging / prod)是同一份代码的多次部署,而非分叉出的多份仓库。共享逻辑应拆为独立依赖,而不是在多个 codebase 间复制。
II. Dependencies — 显式声明并隔离依赖
通过 go.mod、package.json、requirements.txt 等显式声明依赖,并用虚拟环境或容器隔离,不依赖隐式的系统全局包。构建与运行环境的依赖图应可复现。
III. Config — 配置存于环境
将环境相关配置(数据库 URL、密钥、第三方凭证)从代码中剥离,以环境变量等方式注入。配置变更不应触发重新构建;密钥不应进入版本库。
IV. Backing Services — 后端服务当作附属资源
数据库、缓存、消息队列、对象存储均为可替换的附属资源,通过 URL 或连接串附着。本地 Postgres 与云上 RDS 应只差配置,不差代码。
V. Build, Release, Run — 严格分离构建与运行
构建产出可执行产物;发布将产物与某次配置快照绑定;运行启动该发布版本。三者单向流动,运行阶段不应修改代码或向镜像打补丁。
VI. Processes — 应用以无状态进程运行
进程不保存本地会话或磁盘状态;需持久化的数据放入 backing service。任意进程被替换后,对外行为应保持一致。
VII. Port Binding — 通过端口绑定导出服务
应用自包含地监听端口提供服务,不依赖将请求「注入」传统应用服务器。前置可为反向代理或 Ingress,但服务自身应可独立暴露 HTTP 等协议。
VIII. Concurrency — 通过进程模型扩展
将不同类型的工作拆为不同类型的进程(如 web、worker、clock),通过水平增加进程数扩展,而不是把全部负载塞进单一巨型进程。
IX. Disposability — 快速启动与优雅终止
进程应能快速启动,并在收到 SIGTERM 时优雅收尾(停止接新请求、排空在途工作)。这使部署、弹性伸缩与故障转移成本更低。
X. Dev/Prod Parity — 开发与生产尽量一致
缩短时间差(频繁部署)、人员差(开发与运维协作)与工具差(开发与生产使用同类 backing service)。「开发用 SQLite、生产用 Oracle」是典型反例。
XI. Logs — 日志作为事件流
应用将日志写入 stdout / stderr,不自行管理文件轮转或集中收集;由执行环境负责汇聚、索引与告警。
XII. Admin Processes — 管理任务当作一次性进程
数据库迁移、一次性脚本、REPL 诊断等,应与正式应用使用同一份代码与配置,作为一次性进程执行完毕即退出,而不是维护一套独立的「运维专用」环境。
实践含义
十二条不必教条式全部满足。更常见的用法是在架构评审中逐条对照:配置是否进入镜像、进程失败后状态是否可恢复、日志是否仅输出到标准流等。偏离可以发生,但应明确其代价与风险。