【问题标题】:Capistrano and environment variablesCapistrano 和环境变量
【发布时间】:2014-07-03 13:40:26
【问题描述】:

我已改用 environment variables for configuration,它运行良好 - 除非我必须使用 capistrano 部署或运行​​任务。

Capistrano 3 似乎会执行以/usr/bin/env 为前缀的每个命令,这会清除我通过.bashrc 设置的所有环境变量。

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

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

【问题讨论】:

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


    【解决方案1】:

    你最好看看difference between ENVIRONMENT VARIABLES and SHELL VARIABLES

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

    您最好将 ENV 变量放入:

    /etc/environment
    

    像这样:

    export ENVIRONMENT_VAR=value
    

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


    更新

    你试过了吗

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

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

    【讨论】:

    • 我需要为单个用户设置变量,但可用于进程运行。我在 .bashrc 中有export FOO=BAR,这在 SSH 中运行良好。只是不在 Capistrano。
    • Hmmmmmmmm - 让我看看!感谢回复
    • default_environment 似乎没有效果,很奇怪。我正在运行一个与测试环境变量和BASH_VERSION 相呼应的测试任务。显示BASH_VERSION,测试变量为空
    • 您的/etc/environment.bashrc 中的环境变量是否存在?
    • 啊,capistrano3 使用的是default_env,而不是default_environment (github.com/capistrano/capistrano/pull/564)。这似乎奏效了。不太理想,但它会为我工作:)
    【解决方案2】:

    虽然已经回答了这个问题,但我将把它留在这里,以防其他人遇到与我相同的情况。

    Capistrano 确实加载.bashrc。但是,如果您会注意到文件顶部有这样的内容:

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

    解决方案是简单地将任何设置放在此之上,Capistrano 可以按照我的意愿工作。

    this GitHub issue 也提到了此解决方案。

    【讨论】:

    • 像魅力一样工作,比上述解决方案简单。
    • 这对我使用 Rails 4.2 应用程序和 Capistrano3 有所帮助。 Rails 正在寻找由 ENV 变量设置的数据库密码和 secret_key_base 之类的东西......我已将其添加到我的 bashrc 文件的末尾......但这些并没有绑定,所以一切都在接近结束时崩溃部署。
    • 这对我在花费数小时试图找到正确的解决方案后有所帮助。非常感谢!
    • 谢谢!我已将所有客户配置移至 .bashrc 文件的顶部。
    【解决方案3】:

    为了调试问题更新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
    

    现在运行cap staging debug:env。你应该可以看到ENV变量的有效配置。

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

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

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

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

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

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

    【讨论】:

      【解决方案4】:

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

      我前段时间创建了一个 Capistrano 库 (capistrano-env_config),用于跨集群管理和同步环境变量,该库完全通过修改 /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
      

      【讨论】:

        【解决方案5】:

        我确定的解决方案是:

        1. 在我需要部署到的所有服务器的 /etc/ssh/sshd_config 中启用 PermitUserEnvironment 选项。
        2. 为我部署到的每个用户的主目录添加一个 ~/.ssh/environment 文件,其中 env vars 以 KEY=VALUE 对的形式(我通过它自己的用户将每个应用程序和服务部署到该用户的主目录)。

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

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

        1. 使用“export KEY=VALUE”在用户的 .bashrc 中设置我的环境变量。 (所以当我以交互方式 SSH 时它们存在。)
        2. 使用“KEY=VALUE”在用户的 .ssh/environment 文件中设置我的环境变量。 (所以当 Capistrano SSH 进入时它们存在。)
        3. 在 /etc/init/puma.conf 的“脚本”部分设置我的环境变量。 (所以当 Puma/Rails 启动时它们就存在了。)

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

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

        【讨论】:

        • “只使用 ENV 变量”他们说!!把它们放在三个地方真是太痛苦了!如果它的唯一原因是防止将机密放入源代码控制文件中,为什么不将它们添加到不在源代码控制中的配置文件中?
        • 我已经放弃了我之前为那个项目构建的所有东西,并重新开始使用全新的更好的技术:Docker、Thin、Sinatra、Sequel 和 etcd。现在正在开发一个工具来存储/从 etcd 中检索生产机密。不再有 Rails、Puppet、Capistrano、SSH、环境变量和所有其他笨重的垃圾。我还没说完,就已经天壤之别了。
        • 3.在 /etc/init/puma.conf 的“脚本”部分设置我的环境变量。 (所以当 Puma/Rails 启动时它们就存在了。) - 这对我有用!非常感谢!
        猜你喜欢
        • 2013-05-29
        • 2014-07-12
        • 1970-01-01
        • 2018-11-03
        • 1970-01-01
        • 1970-01-01
        • 2011-12-12
        相关资源
        最近更新 更多