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

How to access environment variables during Capistrano deploy?

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

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

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

这很有魅力。我的应用程序 ENV 具有所有正确的变量,Secrets.yml 已正确填充...一切正常,除了通过 ssh 使用 Capistrano 进行部署时。

在我的 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 不使用远程环境?我如何在服务器端或我的部署脚本中修改我的配置来解决这个问题?

感谢您的帮助。

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

Capistrano 是一个 运行 在您本地机器上的程序。所以 Capistrano 中的 ENV 看到的是你的本地环境,而不是服务器的。 Capistrano 无法使用纯 Ruby 代码 "see" 远程 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 FAQ 中有详细解释: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.

的最顶部成功导出了变量