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

Mik*_*e A 1 capistrano ruby-on-rails 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
Run Code Online (Sandbox Code Playgroud)

这就像一个魅力。我的应用程序ENV具有所有正确的变量,Secrets.yml并已正确填充...除了通过ssh与Capistrano进行部署外,其他所有功能均正常运行。

在我的deploy.rb书中,我认为以下内容是相对的:

set :ssh_options, {
forward_agent: true,
paranoid: true,
keys: "~/.ssh/id_rsa.pub"
}
Run Code Online (Sandbox Code Playgroud)

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

谢谢您的帮助。

Mat*_*son 5

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

Capistrano是在本地计算机上运行的程序。因此,ENV在Capistrano内部可以看到您的本地环境,而不是服务器的环境。Capistrano无法ENV用普通的Ruby代码“查看”远程,因为组成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
Run Code Online (Sandbox Code Playgroud)

这将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-not-in-capistrano/

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

您可以production.rb像这样在Capistrano配置本身中指定它们:

set :default_env, { var1: "val1", var2: "val2" }
Run Code Online (Sandbox Code Playgroud)

Capistrano然后将在执行SSH命令时显式设置该环境。

或者,您可以使用dotenv之类的工具,该工具使Rails可以从特殊文件中读取变量变量,而不必依赖执行环境。

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