在Ubuntu上使用nginx和Passenger时放置环境变量的位置

时间:2012-04-09 22:24:24

标签: ruby-on-rails ubuntu environment-variables

我正在尝试建立一个类似于heroku的系统,我将秘密密钥存储在环境变量中,然后从我的rails应用程序中访问它们,如下所示:

secret = ENV['EMAIL_PASSWORD']

我知道heroku可以让你heroku config:add EMAIL_PASSWORD=secret,我想为我自己的运行nginx和Passenger的ubuntu盒做类似的事情。

我应该在export.bashrc中将这些变量添加为.bash_login,以便在系统重启时这些变量会自动设置吗?

我不确定每个文件何时被读入。

13 个答案:

答案 0 :(得分:10)

您可以使用dotenv gem加载.env文件作为环境变量。您可以为不同的环境生成.env文件,而不必将其检入您的存储库。

答案 1 :(得分:7)

请记住,nginx可能不会在与您相同的环境下运行,并且通常(发音为“Apache”)我们通过SetEnv在服务器配置文件中添加env-vars。但是,我相信nginx没有这样的功能......也不需要它。

sudo -E /usr/local/sbin/nginx

运行nginx时,要知道自己的用户env vars。

或者,查看env命令(see here):

env EMAIL_PASSWORD=secret

要回答您的问题,是的,您应该在shell配置文件中使用export语句。

答案 2 :(得分:6)

(这可能是一种矫枉过正,但也许它会有用)

要记住的一些事情:

环境变量在某种程度上是公开的,并且可以像其他进程一样轻松地添加ps(1)命令的选项(如bash中的ps e $$)或查看/proc/*/environ。两者都至少限制在现代系统上的同一用户(或根)。如果你有另一个相当简单的选择,不要依赖它们是秘密的。

~/.bashrc是环境变量的错误位置,因为它们可以在~/.bash_login,〜/ .bash_profile或~/.profile登录时计算一次,具体取决于您的使用情况,并通过直到所有后代的贝壳。相反,~/.bashrc操作往往会在每次shell调用时重新计算(除非明确禁用)。

将bash代码放在~/.profile中可能会混淆其他sh-descendent shell和尝试读取该文件的非shell工具,因此让bash特定的~/.bash_login或-_profile包含bash-具体的事情,并使用. ~/.profile更一般的东西(LESS,EDITOR,VISUAL,LC_COLLATE,LS_COLORS等),对其他工具更友好。

~/.profile中的环境变量应采用旧的Bourne shell形式(VAR=value ; export VAR)。在Linux上,这通常不是关键,但在其他Unixen上,当旧版本的“sh”试图读取它们时,这可能是个大问题。

某些X会话只会阅读~/.profile,而不是~/.bash_login或上面提到的其他会话。如果某个~/.xsession文件尚未以某种方式进行修改,则需要将其修改为. $HOME/.profile

系统范围的设置将改为/etc/profile.d/similar-to-heroku.sh。请注意,“。sh”仅出现,因为该文件将与“。”一起使用。或“源代码” - shell脚本永远不会在任何形式的Unix / Linux中具有命令名扩展名。

当一个sudo转到root时,大多数环境变量会被抛弃,正如ybakos指出的那样。类似的问题出现在crontabs,工作等等。如果有疑问,添加env | sort > /tmp/envvars之类的可疑脚本可以真正帮助调试。

请注意,某些发行版具有shell启动脚本,因此扭曲它们最终会违反bash(1)手册页中给出的顺序。每当您发现默认用户~/.profile检查$ BASH或$ BASH_VERSION时,您可能处于其中一个,嗯......,“有趣”的环境中,并且可能必须通读它们以找出控件的位置流程(他们应该使用特定于bash的~/.bash_profile~/.bash_login,其中包含更通用的~/.profile引用,从而让bash可执行文件完成工作而不必编写$ BASH检查shell代码。)

~/.bash_profile(或~/.bash_login)当然可以包含. ~/.bashrc,但环境变量属于~/.bash_profile(如果是特定于bash)或~/.profile包含它(如果你正在使用这种机制,并为那里的其他所有内容设置了envvars)正如DeWitt所说,只需记住将. ~/.bashrc放在.bash_profile的. ~/.profile和其他环境变量之后,这样就可以了登录和~/.bashrc的所有其他调用都可以依赖已经设置的envvars。示例~/.bash_profile

# .bash_profile
[ -r ~/.profile ] && . ~/.profile  # envvars
[ -r ~/.bashrc ]  && . ~/.bashrc   # functions, per-tty settings, etc.
#---eof

[ -r ... ] && ...适用于任何Bourne shell后代,如果缺少.profile,则不会导致错误/中止(我个人也有~/.profile.d/*.sh设置,但这完全是保留的可选练习)。

请注意,bash只读取它找到的这三个文件中的第一个文件:

~/.bash_profile
~/.bash_login
~/.profile

...所以一旦你拥有了那个,从bash的角度来看,其他两个的使用完全在用户的控制之下。

答案 3 :(得分:5)

This is documented in nginx。运行worker时,它会删除 TZ之外的所有环境变量。如果要添加环境变量,请将以下内容添加到nginx配置的顶部

# The top of the configuration usually has things like:
user user-name;
pid pid-file-name;

# Add to this:
env VAR1=value1;
env VAR2=value2;

# OR simply add:
env VAR1;
# To inherit the VAR1 from whatever you set in bash

正常export或你在bash中做的任何事情都无法保证传递给nginx,因为init脚本的编写方式(我们不知道他们是否使用了干净的sudo环境等)。所以我宁愿把它们放在nginx配置文件本身,而不是依靠shell来做它。

修改:修复链接

答案 4 :(得分:4)

我在/usr/local/bin文件夹中有一个脚本,用于设置一些env变量然后执行Ruby。我在我的(Apache,而不是Nginx)conf文件中将Ruby的路径定义为/usr/local/bin中的该文件。

示例:

#!/bin/sh

# setup env vars here
export FOO=bar
export PATH_TO_FOO=/bar/bin
export PATH=$PATH:PATH_TO_FOO

# and execute Ruby with any arguments passed to this script
exec "/usr/bin/ruby" "$@"

答案 5 :(得分:2)

你应该阅读这个对另一个问题的回答,它会有所帮助:

https://stackoverflow.com/a/11765775/1217298

答案 6 :(得分:2)

我把它们放在我的nginx配置中,特别是在使用passenger_env_var命令的应用程序的服务器定义中:

server {
    server_name www.foo.com;
    root /webapps/foo/public;
    passenger_enabled on;

    passenger_env_var DATABASE_USERNAME foo_db;
    passenger_env_var DATABASE_PASSWORD secret;
    passenger_env_var SECRET_KEY_BASE the_secret_keybase;
}

这对我有用。有关详细信息,请参阅phusion乘客docs

答案 7 :(得分:1)

已编辑:

好的抱歉,我读得太快,你可以在这里查看如何保存你的ENV变量:

https://help.ubuntu.com/community/EnvironmentVariables

http://www.cyberciti.biz/faq/set-environment-variable-linux/

如果您在本地计算机上使用Nginx作为服务器,则可以将env变量定义到nginx配置文件中。

location / {
...
   fastcgi_param   EMAIL_PASSWORD  secret; #EMAIL_PASSWORD = secret
...
}

答案 8 :(得分:1)

我正在使用rbenv作为版本管理器。对项目存储环境变量的良好解决方案是安装rbenv-vars插件并将它们放在.rbenv-vars文件中。

这是一篇有用的帖子:
Deploying app ENV variables with Rbenv, Passenger and Capistrano

答案 9 :(得分:1)

对于那些正在使用RVM的人。确保您的默认环境文件包含用户的.bashrc和.profile文件

file: $rvm_path/environments/default

找到运行此命令的路径:

ls -lah `whereis rvm`/environments/default

在该文件的第一行之前添加这两行:

source $HOME/.bashrc
source $HOME/.profile

答案 10 :(得分:0)

如果有人遇到与我相同类型的问题,这里有一篇关于不同.bash*文件的简短文章:http://www.joshstaiger.org/archives/2005/07/bash_profile_vs.html

总结:

在大多数情况下: 登录计算机时会读取.bash_profile,并且在启动新终端时会读取.bashrc。对于Mac OSX,将在您启动的每个终端窗口中读取.bash_profile

因此,建议的过程是从.bashrc获取.bash_profile,以便在您登录计算机时设置所有变量。只需将其添加到.bash_profile

即可
if [ -f ~/.bashrc ]; then
   source ~/.bashrc
fi

答案 11 :(得分:0)

为项目保留env变量的最佳位置是/etc/profile.d/YOUR_FILE.sh, Here您可以找到详细说明在哪里保存不同方案的env变量的文档。

答案 12 :(得分:-1)

您必须将导出行添加到主文件夹下的.profile文件中...

正在登录时设置环境变量...