【问题标题】:Set Rails Variable to Different Values for Different Capistrano Environments为不同的 Capistrano 环境将 Rails 变量设置为不同的值
【发布时间】:2014-03-17 09:10:24
【问题描述】:

我有一个 Rails 应用程序,它设置为使用 Capistrano 部署到两个不同服务器之一(取决于用户选择部署到哪个服务器)。我想为 Rails 应用程序创建一个环境变量,该变量会根据网站部署到的服务器而变化。

在我的 Capistrano 部署 (config/deploy.rb) 文件中,我有一个变量“stages”,它有两个选项供用户部署到:

set :stages, %w(production staging)

我尝试在我的环境 (config/environment.rb) 文件中的 if 语句中使用此变量来设置变量,如下所示:

if (:stages == "staging")
    ENV['GLOBAL_EMAIL'] = "email1@domain.com"
else
    ENV['GLOBAL_EMAIL'] = "email2@domain.com"
end

但是,当我对此进行测试时,rails 无法呈现 #{ENV['GLOBAL_EMAIL']}(据我所知,因为该变量未设置或无法访问。

我的问题是:stages 无法访问是否有原因,以及是否有根据环境设置变量的方法/更好的方法?

请注意,即使一种称为 staging 一种称为生产,两种环境都部署了 rails 的生产环境(不是 rails 的测试和生产环境),因此我无法进行测试以查看 rails 运行到哪个环境设置变量。

【问题讨论】:

  • 在红宝石中:stages 是一个符号。你试过stages吗?此外,新版本的 capistrano 通常具有 deploy/stage1.rb 和 deploy/stage2.rb 结构,因此您不必在您所在的舞台上执行这种 if/else 操作。你运行的是什么版本的 Cap?
  • 我使用的是 2.13.5 版本,我确实有两个不同的部署,每个环境一个,将变量放在那里确实更有意义。请原谅我对此的无知,但我现在正试图在我的每个部署文件(对于每个环境)中放置'set :email_var,“email@domain.com”',但是当我测试它并尝试访问 email_var 时,我收到“未定义的局部变量或方法”错误。我以为,默认情况下,部署文件中设置的变量在范围内是全局的?

标签: ruby-on-rails ruby-on-rails-3 environment-variables capistrano


【解决方案1】:

对于初学者,您试图将符号等同于字符串,这将始终返回 false。

同样在 capistrano 中,要获得您在其中部署的环境,您需要 stage 变量。此变量仅在加载后可用,而不是在 ruby​​ 读取文件时可用。这意味着您需要提供一个延迟加载的块。问题是这些是在设置局部变量的上下文中评估的,例如deploy_to

set(:deploy_to) { "/var/www/#{application}/#{stage}" }

这是我的部署脚本中的一个常见设置,其中登台和生产部署到同一台服务器。

你可以试试这样的:

set(:global_email) do
  if stage == 'production'
    ENV['GLOBAL_EMAIL'] = 'email1@example.com'
  else
    ENV['GLOBAL_EMAIL'] = 'email2@example.com'
  end
end

或者另一种处理方式是使用部署阶段特定的文件。

# config/deploy/production.rb
ENV['GLOBAL_EMAIL'] = 'email1@example.com'

# config/deploy/staging.rb
ENV['GLOBAL_EMAIL'] = 'email2@example.com'

更新

我没有注意到提到在 Rails 中渲染值的问题。这当然与 Rails 无关,也不是在初始化 Rails 时 Capistrano 配置文件中设置的任何内容,因为 capistrano 应该只在开发环境中可用。

正确的方法是使用 rails initalizer 并在 Rails 启动时设置变量。

# config/initializer/global_email.rb

if Rails.env.production?
  GLOBAL_EMAIL = 'email1@example.com'
else
  GLOBAL_EMAIL = 'email2@example.com'
end

【讨论】:

  • 我尝试了您的两个建议,但问题似乎是无论我如何在部署文件中设置变量,这些变量都无法在 rails 视图中读取。变量应该在的视图中没有出现任何内容,或者我收到有关未定义局部变量的错误。
  • 哦,我没有意识到你正试图从 Rails 访问它。在这种情况下,您不能这样做,因为 capistrano 与 Rails 无关。像这样的东西属于配置文件或 Rails 初始化程序。
【解决方案2】:

我最终得到的最终解决方案是在我的 Capistrano 部署外部创建一个文件(例如在 /home/[user]/.var/.emails 中),每个服务器上的每个文件都只包含所需的电子邮件(例如email1@domain.com)。然后在environments.rb中:

ENV['GLOBAL_EMAIL'] = begin IO.read("/home/[user]/.vars/.email") rescue "" end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 2018-10-03
    • 2018-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多