Capistrano和环境变量

时间:2014-05-15 08:10:15

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

我已切换到使用environment variables for configuration并且效果非常好 - 除非我必须使用capistrano部署或运行​​任务。

Capistrano 3似乎执行每个前缀为/usr/bin/env的命令,该命令会删除我通过.bashrc设置的任何环境变量。

编辑 - 在做更多的研究时,这可能不是问题,问题可能是因为capistrano作为非登录的非交互式shell执行而且不加载{{1} }或.bashrc。但仍然陷入困境。

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

5 个答案:

答案 0 :(得分:47)

您最好看一下difference between ENVIRONMENT VARIABLES and SHELL VARIABLES

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

您可能最好将ENV vars放入:

/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'
}

答案 1 :(得分:45)

虽然已经回答了这个问题,但我会留下这个,以防其他人处于相同的情况。

Capistrano 加载.bashrc。但如果您在文件顶部注意到这一点:

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

解决方案只是将任何设置置于此之上,而Capistrano就是我想要的。

此解决方案也在this GitHub issue注意到。

答案 2 :(得分:10)

为了使用简单的任务调试问题更新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
  5. ~/.bashrc包含这样的第一行时,之后的任何代码都不会被采购:

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

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

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

    capistrano env variables loading

答案 3 :(得分:1)

您需要在/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

答案 4 :(得分:0)

我解决的解决方案是:

  1. 在我需要部署的所有服务器的/ etc / ssh / sshd_config中启用PermitUserEnvironment选项。
  2. 为每个用户的家庭目录添加一个〜/ .ssh / environment文件,我用env vars以KEY = VALUE对的形式部署(我通过它自己的用户部署每个应用和服务)该用户的家庭目录。
  3. 参考:http://en.wikibooks.org/wiki/OpenSSH/Client_Configuration_Files#.7E.2F.ssh.2Fenvironment

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

    1. 使用&#34;导出KEY = VALUE&#34;在用户的.bashrc中设置我的环境变量。 (所以当我以交互方式进行SSH时它们就存在了。)
    2. 使用&#34; KEY = VALUE&#34;在用户的.ssh / environment文件中设置我的环境变量。 (因此当Capistrano SSH进入时,它们就存在了。)
    3. 在/etc/init/puma.conf' s&#34;脚本&#34;中设置我的环境变量部分。 (所以当Puma / Rails开始时它们就存在了。)
    4. 在多个文件/模板和多种格式(使用导出,不导出...)中维护相同的环境列表是一件很痛苦的事。幸运的是,在使用Capistrano部署之前,通过使用Puppet管理节点的配置,它更容易/更可靠......

      我真的很讨厌linux shell,初始化和dotfiles的整个域名。现在是完全重启的时候了。

相关问题