比如 Rails 4.1 引入的 secrets.yml 中,production 默认的 SECRET_KEY_BASE 是 <%= ENV["SECRET_KEY_BASE"] %>
. 大家在线上部署时候是如何解决这个问题的呢.?
我搜了几个方案分享一下
大意是通过设置 sshd_config 的 PermitUserEnvironment yes
后,再在本端的 ~/.ssh/environment 中手动写环境变量 SECRET_KEY_BASE=66a2caf0d57e376cae89a297656c1224e5951609591374f9ba0a31a77ba36c4fcafd2f
这样通过 capistrano ssh 到对端后对端的环境中就带上了这个变量,于是搞定。
缺点在于如果你要在一个机器上向对端部署多个应用就跪了
rbenv 插件可以读取应用根目录下的 .rbenv-vars 文件,根据文件内容设置环境变量。于是只要在 capistrano 的 deploy.rb 中加上 set :linked_files, %w{config/database.yml .rbenv-vars}
就可以了
缺点是必须要安装 rbenv 和 rbenv-vars. 我在生产环境是直接用自编译的 ruby rpm 包,所以没 rbenv....
两个 gem 的功能都类似,都是提供一种机制能帮你预先把对应的变量放进 ENV Hash 中,其中最大的区别是 dotenv 鼓励你把 .env
文件放入 repo, 方便新开发者直接上手,而 figaro 默认把配置文件加入了 .gitignore
. 见仁见智吧。
另外 figaro 还有一个特性是 integrated with heroku, 通过 figaro heroku:set -e production
命令直接搞定。
直接写 cap 命令呢
namespace :deploy do
desc "Start unicorn"
task :start do
run "cd #{deploy_to}/current/; RAILS_ENV=#{rails_env} SECRET_KEY_BASE=#{ENV['SECRET_KEY_BASE']} bundle exec unicorn_rails -c #{unicorn_path} -D"
end
end
多应用部署同一机器上的情况,在实际很少见吧。。如果有,加前缀也很容易解决。
我的解决方法是,另外建立了一个 secrets.production.yml,部署文件里边让它在最后自动上传覆盖 secrets.yml,而这个文件在 git 里边忽略了的。
#12 楼 @quakewang 你意思是放在 ~/.bash_profile
里面?
我在想有没有办法在应用机上不放任何敏感信息 (数据库密码这样)..敏感信息最多只保留在部署工具机上
应用机都被攻破了,别人也是可以轻易通过控制台获取环境变量的。只要查询到你用的环境变量的 key,查询其值不是很简单的么?所以,应用机都被攻破了,说这些就没得意思了。
我的方案也是把本地的设定转成环境变量去启动远程服务器的 rails 应用
安装 settei gem 以后
先把设定放在 config/environments/production.yml 跟 config/environments/default.yml
rails:
secret_token: foooooo
secret_key_base: barrrrr
然后让 Rails 去读取这设定
# secret_token.rb
Foo::Application.config.secret_token = Setting.dig(:rails, :secret_token)
Foo::Application.config.secret_key_base = Setting.dig(:rails, :secret_key_base)
这样 deploy 时就自动会用 #5 推荐的方式把设定传给远程服务器, 当然要是你使用 heroku 也有类似的功能把设定传给远程服务器。