简体   繁体   English

如何在 capistrano 的 deploy.rb 文件中使用 Rails 5.2 凭据?

[英]How can I use Rails 5.2 credentials in capistrano's deploy.rb file?

I've just updated my Rails app to 5.2, and configured it to use the new config/credentials.yml.enc file.我刚刚将我的 Rails 应用程序更新到 5.2,并将其配置为使用新的config/credentials.yml.enc文件。

When I try to deploy, I get this error:当我尝试部署时,我收到此错误:

NameError: uninitialized constant Rails
/Users/me/Documents/project/config/deploy.rb:27:in `<top (required)>'

That's pointing to this line in my config/deploy.rb file:这指向我的config/deploy.rb文件中的这一行:

set :rollbar_token, Rails.application.credentials[:rollbar_token]

So it appears that while capistrano is running, it doesn't have access to Rails.application.credentials .因此,当 capistrano 运行时,它似乎无法访问Rails.application.credentials

How are you all handling this?你们都怎么处理这件事? I've got some ideas...我有一些想法...

  • Set this one variable as an ENV variable将此变量设置为ENV变量
    • I don't love how this separates/customizes this one setting我不喜欢这如何分离/自定义这一设置
  • Somehow make it so capistrano has access to Rails.application.credentials不知何故,capistrano 可以访问Rails.application.credentials
    • I don't know if this is a good idea or if there are other things I need to be aware of if I go this route我不知道这是否是个好主意,或者如果我走这条路,是否还有其他需要注意的事情
  • Remove deploy tracking in rollbar删除滚动条中的部署跟踪
    • 🤷‍♂️ 🤷‍♂️

Put the following line(s) on top of your config/deploy.rb将以下行放在config/deploy.rb的顶部

# config/deploy.rb
require File.expand_path("./environment", __dir__)

This include make constants like Rails.application accessible in files like config/deploy/production.rb .这包括让像Rails.application这样的常量可以在config/deploy/production.rb等文件中访问。 Now things like the following are possible:现在可能会出现以下情况:

# config/deploy/staging.rb
server "production.lan", user: "production", roles: %w{app db web}
set :stage, :production
set :branch, "development"
set :pg_password, Rails.application.credentials[:staging][:postgres][:password]

1. Upload master.key the file on the server (user read-only) like so: 1.上传master.key文件到服务器(用户只读),如下:

namespace :setup do
  desc "setup: copy config/master.key to shared/config"
  task :copy_linked_master_key do
    on roles(fetch(:setup_roles)) do
      sudo :mkdir, "-pv", shared_path
      upload! "config/master.key", "#{shared_path}/config/master.key"
      sudo :chmod, "600", "#{shared_path}/config/master.key"
    end
  end
  before "deploy:symlink:linked_files", "setup:copy_linked_master_key"
end

Put it in your lib/capistrano/tasks/setup.rake把它放在你的lib/capistrano/tasks/setup.rake

2. Ensure file is linked 2.确保文件链接

In deploy.rb :deploy.rb

set :linked_files, fetch(:linked_files, []).push("config/master.key")

3. Ensure Capfile loads the task: 3. 确保 Capfile 加载任务:

Make sure your Capfile has the line确保您的Capfile有该行

# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }

我解决了如下问题:

set :rollbar_token, YAML.load(`rails credentials:show`)['rollbar_token']
require File.expand_path("./environment", __dir__)
puts App::Application.credentials.rollbar_token

The way I solve this is to declare a $ROLLBAR_ACCESS_TOKEN environment variable on the server.我解决这个问题的方法是在服务器上声明一个$ROLLBAR_ACCESS_TOKEN环境变量。 I place it at the top of ~deployer/.bashrc like this:我把它放在~deployer/.bashrc的顶部,如下所示:

export ROLLBAR_ACCESS_TOKEN=...

Then I integrate with Capistrano by defining this task:然后我通过定义这个任务与 Capistrano 集成:

task :set_rollbar_token do
  on release_roles(:all).first do
    set :rollbar_token, capture("echo $ROLLBAR_ACCESS_TOKEN").chomp
  end
end

before "rollbar:deploy", "set_rollbar_token"

It seemed to me non-ideal to load the whole of Rails here, or to have to read command line output, so here's an alternative solution:在我看来,在这里加载整个 Rails 或必须读取命令行输出似乎并不理想,所以这里有一个替代解决方案:

require "active_support/encrypted_configuration"
require "active_support/core_ext/hash/keys"

module CredentialLoader
  def read_credentials(environment:)
    YAML.load(
      ActiveSupport::EncryptedConfiguration.new(
        config_path: "config/credentials/#{environment}.yml.enc",
        key_path: "config/credentials/#{environment}.key",
        env_key: environment.to_s,
        raise_if_missing_key: true
      ).read
    )   
  end 
end

Then you can do this in your deploy.rb :然后您可以在deploy.rb中执行此操作:

include CredentialLoader
set :rollbar_token, read_credentials(environment: fetch(:stage))["rollbar_access_token"]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM