我在 Capistrano 中处理敏感信息(密码等)的方式与我通常处理它们的方式相同:我使用APP_CONFIG
来自未检入版本控制的 YAML 文件的哈希。这是一种经典技术,例如在RailsCast #226中介绍过,或者参见这个 StackOverflow 问题。
在 Capistrano 中使用这种方法时,您必须做一些不同的事情:
通常APP_CONFIG
是从你的config/application.rb
(所以它发生得足够早,可以在其他任何地方使用);但 Capistranocap
任务不会加载该文件。但是您也可以从中加载它config/deploy.rb
;config/deploy.rb
这是使用需要用户名/密码的 HTTP 存储库的人为文件的顶部。
require 'bundler/capistrano'
APP_CONFIG = YAML.load_file("config/app_config.yml")
set :repo_user, APP_CONFIG['repo_user']
set :repo_password, APP_CONFIG['repo_password']
set :repository, "http://#{repo_user}:#{repo_password}@hostname/repositoryname.git/"
set :scm, :git
# ...
该config/app_config.yml
文件未检入版本控制(将该路径放入您的.gitignore
或类似的);我通常签入config/app_config.yml.sample
显示需要配置的参数:
repo_user: 'usernamehere'
repo_password: 'passwordhere'
如果您将APP_CONFIG
用于您的应用程序,它可能需要在不同的部署主机上具有不同的值。因此,让您的 Capistrano 设置在shared/
签出后从目录到每个版本的符号链接。您希望在部署过程的早期执行此操作,因为应用迁移可能需要数据库密码。所以在你的config/deploy.rb
放这个:
after 'deploy:update_code', 'deploy:symlink_app_config'
namespace :deploy do
desc "Symlinks the app_config.yml"
task :symlink_app_config, :roles => [:web, :app, :db] do
run "ln -nfs #{deploy_to}/shared/config/app_config.yml #{release_path}/config/app_config.yml"
end
end
现在,对于问题的第二部分(关于部署到多个主机),您应该为每个主机配置单独的 Capistrano“阶段”。您将所有阶段通用的所有内容放入config/deploy.rb
文件中,然后将每个阶段独有的所有内容放入config/deploy/[stagename].rb
文件中。您将有一个部分config/deploy.rb
定义阶段:
# Capistrano settings
require 'bundler/capistrano'
require 'capistrano/ext/multistage'
set :stages, %w(preproduction production)
set :default_stage, 'preproduction'
(您可以随意调用阶段;Capistrano 阶段名称与 Rails 环境名称是分开的,因此阶段不必称为“生产”。)现在,当您使用命令时,在和cap
之间插入阶段名称cap
目标名称,例如:
$ cap preproduction deploy #deploys to the 'preproduction' environment
$ cap production deploy #deploys to the 'production' environment
$ cap deploy #deploys to whatever you defined as the default