What · 是什么
一个代码库,多环境部署,版本控制跟踪一切
十二要素应用总是被版本控制系统(VCS)跟踪,例如 Git、Mercurial 或 Subversion;修订跟踪数据库的一份副本称为代码仓库,常简写为 code repo 或 repo。
codebase 指任意单个仓库(如集中式 VCS 的 Subversion),或共享同一根提交的一组仓库(如去中心化 VCS 的 Git)。
codebase 与应用之间永远存在一对一关系:若存在多个 codebase,那它不是应用而是分布式系统,分布式系统的每个组件各自是独立应用,可各自符合十二要素。
多个应用共享同一份代码是十二要素的违规行为,正确解法是把共享代码抽取为库,经依赖管理器引入,而非在各应用中复制。
一个应用只有一个 codebase,但会有许多 deploy;deploy 是应用的一个运行实例,通常是生产站点加一个或多个预发布(staging)站点。
每位开发者的本地开发环境也各自运行一份应用副本,每份副本同样算作一个 deploy,是同一应用的多个运行实例之一。
所有 deploy 共享同一 codebase,尽管各 deploy 可能运行不同版本:例如开发者有尚未部署到 staging 的提交,staging 有尚未部署到生产的提交。
正因为所有 deploy 共享同一 codebase,它们才可被识别为同一应用的不同 deploy,各处版本差异因此清晰可追踪、可解释。
Why · 为什么
原理 · Principle
版本控制跟踪一切是应用长期演变的基础,使每次变更都可追溯、可审查、可回滚,避免混乱的临时改法,这使所有 deploy 都能追溯到唯一的代码来源,版本归属始终清晰。
codebase 与应用一对一是可部署性的根基:任何部署物都能追溯到唯一代码来源,从根上避免多个代码源之间漂移。
多应用共享一份代码会破坏各自的独立演进与独立部署节奏,违背应用边界应清晰划分的基本原则,版本与部署的对应关系因此可解释、可审计。
共享代码抽成库并经依赖管理器引入,使共享的粒度、版本与发布节奏都处于可控状态,而非复制粘贴失控,这是应用可部署性与长期演进的根基。
单一 codebase 使所有 deploy 可被标识为同一应用的不同版本,版本差异可追踪,协作边界自然清晰。
How · 怎么做
用一个版本控制系统(Git/Mercurial/Subversion 等)跟踪应用的全部代码与配置模板,保证任何状态可重建。
保持一个 app 对应唯一 codebase,多组件系统按分布式系统拆分,每个组件各自独立管理自己的代码库。
为每个 deploy(生产、staging、开发本地)维护独立运行实例,但全部共用同一个 codebase,不另起代码来源。
各 deploy 运行不同代码版本属正常状态,通过提交在流水线中依次推进传播,用同一 codebase 追踪进度。
把跨应用共享的代码抽取为独立库,放入各自 repo,经依赖声明引入使用,而非复制进各应用,这使所有 deploy 都能追溯到唯一的代码来源,版本归属始终清晰。
配合依赖原则(Bundler/Pip 等)管理共享库版本,保证构建确定性,降低集成风险,版本与部署的对应关系因此可解释、可审计。
明确区分 codebase(代码来源)与 deploy(运行实例)两个概念,避免混用导致版本与部署归属混乱。
案例 · Cases
| 代表性案例 |
|---|
| Git:去中心化 VCS,仓库间共享根提交,是现代项目的主流选择,也是 Heroku 平台日常使用的版本控制工具。 |
| Mercurial:去中心化 VCS,作为 Git 之外的常见备选,同样支持共享根提交的多仓库模型。 |
| Subversion:集中式 VCS,codebase 即单个中央仓库,适合需要集中管控的开发场景。 |
| 生产站点 + 一个或多个 staging 站点 + 每位开发者本地副本,共同构成同一 app 的多个 deploy 运行实例。 |
| 开发者本地有尚未部署的提交、staging 有尚未上生产的提交——同一 codebase 不同版本在流水线中逐级推进的典型节奏。 |
| 多处版本并存:同一时刻各 deploy 允许处于不同提交,但全部指向同一个 codebase,归属清晰。 |
反模式 · Anti-patterns
- 多个 codebase 却宣称是一个应用——实质是分布式系统,各组件应分别符合十二要素并独立管理,这使所有 deploy 都能追溯到唯一的代码来源,版本归属始终清晰。
- 多个应用共享同一份代码——正确做法是把共享代码抽成库,经依赖管理器引入,而非直接共用,版本与部署的对应关系因此可解释、可审计。
- 把共享代码直接复制进各应用仓库,会导致重复、漂移与维护灾难,一处更新需逐处同步,这是应用可部署性与长期演进的根基。
- 把不同应用塞进同一 codebase,使版本与部署互相干扰,难以独立发布,破坏应用边界,协作与发布边界因此保持清晰,避免多个代码源之间的漂移。
- 共享逻辑在各应用间以复制粘贴维护,一旦上游更新需逐处手工同步,极易失配并引入隐性缺陷,保证任何运行实例都能对应到确定的一份代码历史。
实践资源 · 源码引用
| 路径 | 说明 |
|---|---|
| 08-source/app-content-en/codebase.md | I. Codebase 原文:codebase/repo 定义、与 app 的一对一关系、deploy 概念、共享代码抽库 |
| 08-source/app-content-en/dependencies.md | 共享代码经依赖管理器引入的交叉引用 |
| 08-source/app-content-en/background.md | 方法论背景:Heroku 数百应用开发经验与防软件腐蚀动机 |
| 08-source/app-content-en/intro.md | 方法论总纲:声明式格式/与 OS 契约/可移植性目标 |