当前位置: 首页>>技术教程>>正文


在Ubuntu上使用Nginx和Passenger时在何处放置环境变量

, ,

问题描述

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

secret = ENV['EMAIL_PASSWORD']

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

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

我不确定何时读入这些文件中的每个文件。

最佳方案

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

次佳方案

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

sudo -E /usr/local/sbin/nginx

在运行nginx时要注意您自己的用户环境变量。

或者,签出env命令(see here):

env EMAIL_PASSWORD=secret

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

第三种方案

This is documented in nginx。运行工作程序时,它将除去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(我们不知道它们是否在干净的环境中使用sudo等)。因此,我宁愿将它们放在nginx配置文件本身中,而不要依赖于shell来执行此操作。

编辑:修复链接

第四种方案

(这可能是一个过大的杀伤力,但也许会有用)

注意事项:

环境变量在某种程度上是公共的,并且可以被其他进程轻易地看到,就像在ps(1)命令中添加了一个选项(如bash中的ps e $$)或查看/proc/*/environ一样,尽管现代环境中它们至少都限于同一用户(或root)系统。如果您还有另一个相当简单的选择,请不要依赖于它们是秘密的。

~/.bashrc是环境变量的错误位置,因为它们可以在登录时一次在~/.bash_login,〜/.bash_profile或~/.profile中进行计算,具体取决于您的使用情况,并向下传递给所有后代shell。相反,~/.bashrc操作倾向于在每次shell调用时重新计算(除非明确禁用)。

将bash代码放入~/.profile可能会使尝试读取该文件的其他sh依赖的shell和非shell工具混淆,因此让bash特定的~/.bash_login或-_profile包含bash特定的内容,并使用. ~/.profile进行更一般的操作(LESS,EDITOR,VISUAL,LC_COLLATE,LS_COLORS等)比其他工具更友好。

~/.profile中的环境变量应采用旧的伯恩壳格式(VAR=value ; export VAR)。在Linux上,这通常并不重要,尽管在其他Unixen上,当较旧版本的”sh”尝试读取它们时,这可能是一个大问题。

某些X会话只会读取~/.profile,而不会读取~/.bash_login或上述其他会话。有些人会寻找一个需要修改的~/.xsession文件,以使其具有. $HOME/.profile(如果还没有)。

可以将System-wide设置放到类似/etc/profile.d/similar-to-heroku.sh的位置。请注意,仅存在”.sh”,因为该文件将与”.”或”source”一起使用-Shell脚本在任何形式的Unix /Linux中都不应具有command-name扩展名。

ybakos指出,当一个sudo植根时,大多数环境变量都会消失。类似的问题也会出现在crontab,作业等中。如果有疑问,添加env | sort > /tmp/envvars或类似的可疑脚本可以真正帮助调试。

请注意,有些发行版具有shell启动脚本,因此它们被扭曲实际上最终违反了bash(1)手册页中给出的顺序。每当您找到默认用户~/.profile检查$ BASH或$ BASH_VERSION时,您可能就处于以下环境之一,嗯… “interesting”环境中,并且可能必须通读它们以找出控制流向何处去(它们应该是使用bash-specific ~/.bash_profile~/.bash_login,通过引用包含更通用的~/.profile,从而使bash可执行文件可以工作,而不必在 shell 程序代码中编写$ BASH检查。

~/.bash_profile(或~/.bash_login)当然可以包含. ~/.bashrc,但是环境变量属于~/.bash_profile(如果为bash-specific)或~/.profile包含在其中(如果您使用了此方法,那么只要声明了),只要您使用了此功能,就可以了请记住在.bash_profile的. ~/.profile和其他环境变量之后放置. ~/.bashrc,以便登录和~/.bashrc的所有其他调用都可以依赖于已设置的envvar。一个示例~/.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的角度来看,一旦拥有了一个,其他两个的使用完全在用户的控制之下。

第五种方案

我在/usr/local/bin文件夹中有一个脚本,该脚本设置了一些环境变量,然后执行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" "$@"

第六种方案

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


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;
}

这对我有用。有关更多信息,请参阅轻客乘客docs

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/7670.html,未经允许,请勿转载。