Heroku-style config management w

作者: hooopo | 来源:发表于2015-12-12 09:18 被阅读388次

    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是一个不错的选择。

    相关文章

      网友评论

      本文标题:Heroku-style config management w

      本文链接:https://www.haomeiwen.com/subject/ubiyhttx.html