Ruby-on-rails Capistrano 和环境变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23672631/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 23:38:03  来源:igfitidea点击:

Capistrano and environment variables

ruby-on-railsenvironment-variablescapistranocapistrano3

提问by Rahul Sekhar

I've switched to using environment variables for configurationand it works very well - except when I have to deploy or run tasks with capistrano.

我已经改用环境变量进行配置,而且效果很好——除非我必须使用 capistrano 部署或运行​​任务。

Capistrano 3 seems to execute each command prefixed with /usr/bin/envwhich erases any environment variables I've set through .bashrc.

Capistrano 3 似乎执行每个命令的前缀,/usr/bin/env这些命令会擦除我通过.bashrc.

EDIT- on doing some more reasearch, this might not be the issue, the issue might be because capistrano executes as a non-login, non-interactive shell and does not load .bashrcor .bash_profile. Still stuck, though.

编辑- 在进行更多研究时,这可能不是问题,问题可能是因为 capistrano 作为非登录、非交互式 shell 执行并且不加载.bashrc.bash_profile. 不过还是卡住了。

What would be the best way of making sure the environment vars are set when capistrano executes its tasks?

确保在 capistrano 执行其任务时设置环境变量的最佳方法是什么?

回答by Richard Peck

You might be best looking at the difference between ENVIRONMENT VARIABLESand SHELL VARIABLES

你可能最好看看之间区别ENVIRONMENT VARIABLESSHELL VARIABLES

When you fire SSH, your app will load the SHELL variables which are defined in your .bashrcfile. These only exist for the life of the shell, and therefore, we don't use them as much as ENVvars

当您启动 SSH 时,您的应用程序将加载在您的.bashrc文件中定义的 SHELL 变量。这些只存在于 shell 的生命周期中,因此,我们不会像ENVvars那样使用它们

You may be better putting the ENVvars in:

您可能最好将ENVvars 放入:

/etc/environment

Like this:

像这样:

export ENVIRONMENT_VAR=value

This will make the variables available throughout the system, not just in different shell sessions

这将使变量在整个系统中可用,而不仅仅是在不同的 shell 会话中



Update

更新

Have you tried

你有没有尝试过

Capistrano: Can I set an environment variable for the whole cap session?

Capistrano:我可以为整个 cap 会话设置环境变量吗?

set :default_env, { 
  'env_var1' => 'value1',
  'env_var2' => 'value2'
}

回答by Delameko

Although this has been answered, I'm going to leave this here in case anyone else is in the same situation I was.

虽然这已经得到了回答,但我将把它留在这里,以防其他人遇到和我一样的情况。

Capistrano doesload .bashrc. But if you'll notice at the top of the file there is this:

Capistrano确实加载了.bashrc. 但是,如果您会注意到文件顶部有:

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

The solution was simply to put any setup above this and Capistrano works how I want.

解决方案只是将任何设置放在此之上,而 Capistrano 可以按照我想要的方式工作。

This solution was also noted at this GitHub issue.

此解决方案也在此 GitHub 问题 中注明。

回答by Tombart

In order to debug the issue update config/deploy.rbwith a simple task:

为了config/deploy.rb使用简单的任务调试问题更新:

namespace :debug do
  desc 'Print ENV variables'
  task :env do
    on roles(:app), in: :sequence, wait: 5 do
      execute :printenv
    end
  end
end

now run cap staging debug:env. You should be able to see effective configuration of ENVvariables.

现在运行cap staging debug:env。您应该能够看到ENV变量的有效配置。

The order and names of files are dependent on your distribution, e.g. on Ubuntu the sourcing sequence is following:

文件的顺序和名称取决于您的发行版,例如在 Ubuntu 上,采购顺序如下:

  1. /etc/environment
  2. /etc/default/locale
  3. /etc/bash.bashrc
  4. ~/.bashrc
  1. /etc/environment
  2. /etc/default/locale
  3. /etc/bash.bashrc
  4. ~/.bashrc

When ~/.bashrccontains first lines like this, any code afterwards won't be sourced:

~/.bashrc包含这样的第一行时,之后的任何代码都不会被引用:

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

To understand how capistranoloads ENV variables this chart (source) might be helpful.

要了解如何capistrano加载 ENV 变量,此图表()可能会有所帮助。

Most likely the ~/.bash*file is not loaded due to non-interactive session.

~/.bash*由于非交互式会话,该文件很可能未加载。

capistrano env variables loading

capistrano 环境变量加载

回答by Itay Grudev

You need to set environment variables in the /etc/environmentfile to make them available to all users and process within a system. Environment variables in the .bashrcor .bash_profilefiles are only available within a shell session and not for automatically spawned processes and services.

您需要在/etc/environment文件中设置环境变量,以使它们可供系统内的所有用户和进程使用。.bashrc.bash_profile文件中的环境变量仅在 shell 会话中可用,不能用于自动生成的进程和服务。

I made a Capistrano library (capistrano-env_config) some time ago for managing and syncing environment variables across a cluster which works exactly by modifying the /etc/environmentfile. It's easy to use and is similar to how you can set environment variables with the Heroku toolbelt. Here are some examples:

capistrano-env_config前段时间我制作了一个 Capistrano 库 ( ),用于管理和同步跨集群的环境变量,该库通过修改/etc/environment文件完全正常工作。它易于使用,类似于使用 Heroku 工具带设置环境变量的方式。这里有些例子:

cap env:list
cap env:get[VARIABLE_NAME, VARIABLE_NAME, ...] 
cap env:unset[VARIABLE_NAME, VARIABLE_NAME, ...] 
cap env:set[VARIABLE_NAME=VALUE, VARIABLE_NAME=VALUE, ...] 
cap env:sync

回答by odigity

The solution I settled on was:

我确定的解决方案是:

  1. Enable the PermitUserEnvironment option in the /etc/ssh/sshd_config of all servers I need to deploy to.
  2. Add a ~/.ssh/environment file for each user's home dir I deploy to with env vars in the form of KEY=VALUE pairs (I deploy every app and service via it's own user to that user's home dir).
  1. 在我需要部署到的所有服务器的 /etc/ssh/sshd_config 中启用 PermitUserEnvironment 选项。
  2. 为我部署到的每个用户的主目录添加一个 ~/.ssh/environment 文件,并以 KEY=VALUE 对的形式使用环境变量(我通过自己的用户将每个应用程序和服务部署到该用户的主目录)。

Reference: http://en.wikibooks.org/wiki/OpenSSH/Client_Configuration_Files#.7E.2F.ssh.2Fenvironment

参考:http: //en.wikibooks.org/wiki/OpenSSH/Client_Configuration_Files#.7E.2F.ssh.2Fenvironment

It's actually worse than that. I use Upstart to manage Puma/Rails, and need the env vars set there as well. So, after days of experimentation, I ended up on the following complete but horrific solution:

实际上比这更糟糕。我使用 Upstart 来管理 Puma/Rails,并且还需要在那里设置 env vars。因此,经过几天的实验,我最终得到了以下完整但可怕的解决方案:

  1. Set my env vars in the user's .bashrc using "export KEY=VALUE". (So they exist when I SSH in interactively.)
  2. Set my env vars in the user's .ssh/environment file using "KEY=VALUE". (So they exist when Capistrano SSHs in.)
  3. Set my env vars in /etc/init/puma.conf's "script" section. (So they exist when Puma/Rails starts.)
  1. 使用“export KEY=VALUE”在用户的 .bashrc 中设置我的环境变量。(所以当我通过 SSH 交互时它们存在。)
  2. 使用“KEY=VALUE”在用户的 .ssh/environment 文件中设置我的 env vars。(所以当 Capistrano SSH 进入时它们存在。)
  3. 在 /etc/init/puma.conf 的“脚本”部分设置我的环境变量。(所以它们在 Puma/Rails 启动时存在。)

It's a pain in the ass maintaining the same list of env vars in multiple files/templates and in multiple formats (with export, without export...). Luckily it's made slightly easier/more reliable by using Puppet to manage the configuration of the node before Capistrano is used to deploy to it...

在多个文件/模板和多种格式(带导出,不带导出......)中维护相同的环境变量列表是一件很痛苦的事情。幸运的是,在使用 Capistrano 部署节点之前,通过使用 Puppet 管理节点的配置,它变得更容易/更可靠……

I really hate the entire domain of linux shells, initialization, and dotfiles. It's time for a complete reboot.

我真的很讨厌 linux shell、初始化和 dotfiles 的整个领域。是时候彻底重启了。