Heroku-style config management with capistrano and dotenv

12-factor Style

通常,应用的 配置 在不同 部署 (预发布、生产环境、开发环境等等)间会有很大差异。这其中包括:

  • 数据库,Memcached,以及其他 后端服务 的配置
  • 第三方服务的证书,如 Amazon S3、Twitter 等
  • 每份部署特有的配置,如域名等

有些应用在代码中使用常量保存配置,这与 12-factor 所要求的代码和配置严格分离显然大相径庭。配置文件在各部署间存在大幅差异,代码却完全一致。

判断一个应用是否正确地将配置排除在代码之外,一个简单的方法是看该应用的基准代码是否可以立刻开源,而不用担心会暴露任何敏感的信息。

12-Factor 推荐将应用的配置存储于 环境变量 中( env vars, env )。环境变量可以非常方便地在不同的部署间做修改,却不动一行代码。更多关于12-factor 的内容请访问 12factor.net.

Rails Style 存在的问题

Rails中大部分实践是遵守了 12-Factor 规则,除了日志和配置。Rails Way的配置方式是yml文件,例如:database.yml、secret.yml等。简单的应用使用yml文件和 12-factor 推荐的环境变量其实区别不大,不过当项目不断膨胀,配置数量也随着增加,yml方式变得越来越难以维护。yml存在的问题表现在:

  1. 需要不断的修改.gitignore文件
  2. 搭建各种环境(dev、production、test、staging)时需要不断copy example文件
  3. 配置散落各处
  4. 每增加yml文件,需要在应用里增加load和parse逻辑
  5. 不小心会被签进版本控制里

下面是目前项目的配置文件,每次搭建环境修改这些配置文件是最痛苦的事情...

shared/config$ ls |grep yml
s3.yml
redis.yml
twilio.yml
paypal.yml
sunspot.yml
database.yml
icontact.yml
http_auth.yml
beanstream.yml
commercehub.yml
canada_post.yml
google_content_api.yml

系统环境变量

最直接的方式是使用shell 环境变量:

$ export TWILIO_ACCOUNT_SID=AC1234...
$ export TWILIO_AUTH_TOKEN=abc12...

在Ruby中使用ENV读取:

puts ENV['TWILIO_ACCOUNT_SID']
puts ENV['TWILIO_AUTH_TOKEN']

shell环境变量由于没有持久化,又引出了 .bashrc、.bash_profile、~/.profile、/etc/environment等方式。都不是很完美,权限问题、login shell问题的坑都等着你呢。最重要的是,上面提到这些都不方便应付单机部署多个应用的场景。

Envyable、dotenv、Figaro

EnvyabledotenvFigaro等工具,在应用程序中把配置注入到ENV中避免了上面提到的各种问题。Envyable、dotenv、Figaro 无论是实现上还是使用上其实大同小异,下面只拿dotenv来说:

In Gemfile:

gem 'dotenv-rails', :require => 'dotenv/rails-now'

config/application.rb

Bundler.require(*Rails.groups)
Dotenv::Railtie.load
HOSTNAME = ENV['HOSTNAME']

.env 文件:

S3_BUCKET=YOURS3BUCKET
SECRET_KEY=YOURSECRETKEYGOESHERE

gitignore忽略.env,并且cap设置软链:

set :linked_files, fetch(:linked_files, []).push('config/database.yml', '.env')

调用的时候仍然是 ENV['SECRET_KEY']。当然,dotenv还支持多环境模式,比如 .env.production 文件只对production环境生效。

Heroku-style

dotenv已经很完美了,但用过Heroku的都知道这还不够,看一下Heroku设置环境变量的方式:

heroku config:set GITHUB_USERNAME=joesmith
Adding config vars and restarting myapp... done, v12GITHUB_USERNAME: joesmith

$ heroku config
GITHUB_USERNAME: joesmith 
OTHER_VAR: production

$ heroku config:get 
GITHUB_USERNAMEjoesmith

$ heroku config:unset GITHUB_USERNAME
Unsetting GITHUB_USERNAME and restarting myapp... done, v13

capistrano-twelvefactor + dotenv 可以打造出和Heroku一样酷的体验。

详细的步骤capistrano-twelvefactor上面都有写,下面只说和dotenv配合需要做的:

# config/deploy/production.rb
set :environment_file, deploy_path.join("shared/.env")

after 'config:set',   "deploy:symlink:linked_files"
after 'config:unset', "deploy:symlink:linked_files"

然后就可以使用这几个命令查看和修改环境配置了:

  • bundle exec cap production config:list
  • bundle exec cap production config:set[FOO=bar]
  • bundle exec cap production config:unset[FOO]

注:上面需要capistrano 3 + dotenv,Envyable和Figaro目前无法使用Heroku style.

Multi Server && Apps

对于单台服务器的应用,capistrano-twelvefactor + dotenv 足以应付,同时,由于capistrano支持集群部署,单个应用多服务器其实也是可以搞定的。但有时候不同应用之间其实也需要共享配置文件的,比如,S3配置变化了,依赖这个帐号的所有应用都应该得到同步。另外的一个问题是,对于多服务器场景,配置存储在.env会出现服务器之间配置不同步现象。如果要解决上述问题,可能引入etcdzookeeper是一个不错的选择。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,580评论 18 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,717评论 6 342
  • Heroku平台 Heroku平台的灵活性极高且支持多种编程语言。若想把程序部署到Heroku上,开发者要使用Gi...
    超net阅读 103,637评论 12 56
  • 作者简介:黄庆兵,网易蜂巢首席技术布道师,浙大硕士毕业,从事云计算、Docker、Go等相关开发及技术布道工作;喜...
    43ce3d72fadb阅读 9,206评论 0 11
  • 英文原文来自 https://wagtail.io/blog/deploying-wagtail-heroku/文...
    treelake阅读 2,916评论 0 0