如何在Capistrano部署期间访问环境变量?

时间:2016-07-19 17:30:14

标签: ruby-on-rails capistrano passenger rbenv

我的rails(4.2)应用程序在Ubuntu(14.02)系统上运行Passenger(5.0.28)+ Apache(2.4.7),使用rbenv管理ruby(2.3.0)。我使用Capistrano(3.4.0)进行部署。

我的所有环境变量都是在一个非常简单的profile.d脚本中设置的。

#!/bin/sh
export VAR1=VAL1
export VAR2=VAL2

这就像一个魅力。我的应用ENV包含所有正确的变量,Secrets.yml已正确填充...除了使用Capistrano在ssh上部署时,所有内容都有效。

在我的deploy.rb我有以下我认为是相关的:

set :ssh_options, {
forward_agent: true,
paranoid: true,
keys: "~/.ssh/id_rsa.pub"
}

Capistrano文档非常有限,ssh \ server配置不是我的强项我似乎无法弄清楚为什么Capistrano看不到我的ENV变量。如果我在部署流程期间运行puts ENV.inspect,我会收到诸如"TERM_PROGRAM"=>"Apple_Terminal"和我的本地机器用户信息等内容。为什么Capistrano不使用远程环境?如何在服务器端或部署脚本中修改配置以修复此问题?

感谢您的帮助。

1 个答案:

答案 0 :(得分:4)

首先,我认为需要对术语和Capistrano的执行模型进行一些澄清。

Capistrano是一个在本地计算机上运行的程序。因此,Capistrano中的ENV会看到您当地的环境,而不是服务器。卡皮斯特拉诺无法看到""带有纯Ruby代码的远程ENV,因为组成Capistrano的Ruby代码没有在那里执行。

Capistrano 所做的是使用SSH将命令发送到服务器以在那里执行。 mkdirbundle install等命令。

要看到此说明,请将Capistrano任务添加到执行此操作的部署流程中:

task :puts_remote_env do
  on roles(:all) do
    remote_env = capture("env")
    puts remote_env
  end
end

这将在远程服务器上运行env命令,捕获结果并将其打印到控制台。

我希望这可以让Capistrano更加清晰。

因此,正如您从puts_remote_env输出中看到的那样,profile.d脚本中定义的变量不存在。为什么呢?

这是因为Capistrano正在使用非登录,非交互式SSH会话。在该SSH会话中,您的profile.d脚本未被评估。这在Capistrano常见问题解答中有详细解释:http://capistranorb.com/documentation/faq/why-does-something-work-in-my-ssh-session-but-not-in-capistrano/

您需要找到另一种方法来设置profile.d脚本以外的其他变量。

您可以在Capistrano配置中指定它们(例如production.rb),如下所示:

set :default_env, { var1: "val1", var2: "val2" }

然后,Capistrano将在执行SSH命令时明确设置该环境。

或者您可以使用像dotenv这样的工具,它允许Rails从特殊文件中读取变量变量,而不是依赖于执行环境。

或者您可以尝试使用不同的点文件位置来查看是否有一些仍然在非登录,非交互式会话中进行评估。在Ubuntu上,我已成功导出~/.bashrc顶部的变量。