You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Capistrano任务执行时Rails credentials无法读取对应环境密钥如何解决?

Rails 6 Capistrano自定义任务读取环境对应credentials失败解决方案

问题根源

Rails应用启动时会预加载Rails.application.credentials配置,你在Capistrano任务的with块中动态设置的rails_env、rails_master_key变量,不会触发Rails重新加载credentials配置,因此始终读取初始化时加载的默认全局config/credentials.yml.enc和config/master.key。

解决方案

方案1:手动实例化对应环境的加密配置(推荐)

直接通过ActiveSupport::EncryptedConfiguration加载指定环境的credentials,不会影响全局Rails配置:

task :my_task do
  on roles(:app), in: :sequence, wait: 5 do
    run_locally do
      env = fetch(:rails_env).to_s
      # 手动指定对应环境的配置文件和密钥路径
      creds = ActiveSupport::EncryptedConfiguration.new(
        config_path: Rails.root.join("config", "credentials", "#{env}.yml.enc"),
        key_path: Rails.root.join("config", "credentials", "#{env}.key"),
        env_key: "RAILS_MASTER_KEY",
        raise_if_missing_key: true
      )
      pp creds
      # 直接通过creds.xxx读取对应配置即可
    end
  end
end

方案2:强制重载全局credentials(不推荐,会修改全局配置)

如果必须使用Rails.application.credentials调用,可以手动清空已加载的配置实例触发重载:

task :my_task do
  on roles(:app), in: :sequence, wait: 5 do
    run_locally do
      env = fetch(:rails_env).to_s
      # 手动写入环境变量
      ENV["RAILS_ENV"] = env
      ENV["RAILS_MASTER_KEY"] = File.read(Rails.root.join("config", "credentials", "#{env}.key")).strip
      # 清空已加载的credentials实例触发重载
      Rails.application.instance_variable_set(:@credentials, nil)
      Rails.application.instance_variable_set(:@encrypted_configs, nil)

      pp Rails.application.credentials
    end
  end
end

配套检查项

  • 确认本地存在对应环境的credentials文件:config/credentials/#{环境名}.yml.enc和config/credentials/#{环境名}.key,且key文件有可读权限
  • 如果任务需要在服务器而非本地执行,移除run_locally配置,同时确保服务器环境变量中配置了对应环境的master key,或已将对应环境的key文件上传到服务器对应路径

内容的提问来源于stack exchange,提问作者brcebn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 03:18:04