### 在環境中存儲配置
通常,應用的?*配置*?在不同?[部署](http://12factor.net/zh_cn/codebase)?(預發布、生產環境、開發環境等等)間會有很大差異。這其中包括:
* 數據庫,Memcached,以及其他?[后端服務](http://12factor.net/zh_cn/backing-services)?的配置
* 第三方服務的證書,如 Amazon S3、Twitter 等
* 每份部署特有的配置,如域名等
有些應用在代碼中使用常量保存配置,這與 12-Factor 所要求的**代碼和配置嚴格分離**顯然大相徑庭。配置文件在各部署間存在大幅差異,代碼卻完全一致。
判斷一個應用是否正確地將配置排除在代碼之外,一個簡單的方法是看該應用的基準代碼是否可以立刻開源,而不用擔心會暴露任何敏感的信息。
需要指出的是,這里定義的“配置”并**不**包括應用的內部配置,比如 Rails 的?`config/routes.rb`,或是使用?[Spring](http://spring.io/)?時?[代碼模塊間的依賴注入關系](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html)?。這類配置在不同部署間不存在差異,所以應該寫入代碼。
另外一個解決方法是使用配置文件,但不把它們納入版本控制系統,就像 Rails 的?`config/database.yml`?。這相對于在代碼中使用常量已經是長足進步,但仍然有缺點:總是會不小心將配置文件簽入了代碼庫;配置文件的可能會分散在不同的目錄,并有著不同的格式,這讓找出一個地方來統一管理所有配置變的不太現實。更糟的是,這些格式通常是語言或框架特定的。
**12-Factor推薦將應用的配置存儲于?*環境變量*?中**(?*env vars*,?*env*?)。環境變量可以非常方便地在不同的部署間做修改,卻不動一行代碼;與配置文件不同,不小心把它們簽入代碼庫的概率微乎其微;與一些傳統的解決配置問題的機制(比如 Java 的屬性配置文件)相比,環境變量與語言和系統無關。
配置管理的另一個方面是分組。有時應用會將配置按照特定部署進行分組(或叫做“環境”),例如Rails中的`development`,`test`, 和?`production`?環境。這種方法無法輕易擴展:更多部署意味著更多新的環境,例如?`staging`?或?`qa`。 隨著項目的不斷深入,開發人員可能還會添加他們自己的環境,比如?`joes-staging`?,這將導致各種配置組合的激增,從而給管理部署增加了很多不確定因素。
12-Factor 應用中,環境變量的粒度要足夠小,且相對獨立。它們永遠也不會組合成一個所謂的“環境”,而是獨立存在于每個部署之中。當應用程序不斷擴展,需要更多種類的部署時,這種配置管理方式能夠做到平滑過渡。