在 Ubuntu 上使用 nginx 和Passenger 时在哪里放置环境变量

Posted

技术标签:

【中文标题】在 Ubuntu 上使用 nginx 和Passenger 时在哪里放置环境变量【英文标题】:Where to put environment variables when using nginx and Passenger on Ubuntu 【发布时间】:2012-04-22 06:22:33 【问题描述】:

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

secret = ENV['EMAIL_PASSWORD']

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

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

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

【问题讨论】:

【参考方案1】:

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

【讨论】:

我正在将 dotenv 用于另一个项目,它是您通常用于测试和开发的东西。假设我可以将它用于生产,我喜欢 .env 列出所有环境变量,它很整洁。你在做这个吗? 没有。我没用过。我使用了 Heroku Config 设置,这对我来说看起来非常整洁。从以下博客文章中得到了这个想法:daniel.fone.net.nz/blog/2013/05/20/…【参考方案2】:

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

sudo -E /usr/local/sbin/nginx

在运行 nginx 时,它会知道您自己的用户环境变量。

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

env EMAIL_PASSWORD=secret

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

【讨论】:

【参考方案3】:

(这可能有点矫枉过正,但也许会有用)

注意事项:

环境变量在某种程度上是公开的,其他进程可以很容易地看到,就像在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 中的环境变量应采用旧的 Bourne shell 形式 (VAR=value ; export VAR)。在 Linux 上,这通常并不重要,但在其他 Unixen 上,当旧版本的“sh”试图读取它们时,这可能是一个大问题。

某些 X 会话只会读取 ~/.profile,而不是 ~/.bash_login 或上面提到的其他会话。有些人会寻找~/.xsession 文件,如果它还没有,则需要修改为. $HOME/.profile

系统范围的设置将被放在类似/etc/profile.d/similar-to-heroku.sh 的地方。请注意,“.sh”仅存在,因为该文件将与“.”一起使用。或 "source" - shell 脚本应该从不在任何形式的 Unix/Linux 中具有命令名称扩展名。

正如 ybakos 指出的那样,当一个 sudos 成为 root 时,大多数环境变量都会被丢弃。类似的问题出现在 crontabs、jobs 等中。如果有疑问,添加 env | sort > /tmp/envvars 或类似的可疑脚本确实有助于调试。

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

~/.bash_profile(或~/.bash_login)当然可以包含. ~/.bashrc,但环境变量属于~/.bash_profile(如果特定于bash)或其中包含的~/.profile(如果你正在使用它机制并在其中为其他所有内容提供环境变量)正如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 的角度来看,其他两个的使用完全在用户的控制之下。

【讨论】:

这可能在您的答案中,但我无法解读:您对实际放置环境变量的位置有何建议?【参考方案4】:

This is documented in nginx。它会在运行工作程序时删除所有环境变量 except TZ。如果要添加环境变量,请将以下内容添加到 nginx 配置的 top 中:

# 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来做。

编辑:修复链接

【讨论】:

您对此持肯定态度吗?这是你自己做的吗? 它比存储在 .bashrc 或 .bash_login 中要好得多。 .bashrc/.bash_login 是特定于用户的,不能保证在某些情况下被调用(比如当你使用 sudo 时,或者从新贵脚本等) nginx 中的 env 与 rails 可用的 ENV 不同,对吧?这是否是经过验证的答案(意味着您正在这样做)? 我不得不投反对票,因为正如@oma 所说,rails 应用程序无权访问您在 nginx 配置中设置的变量。我已尝试完全按照您的解释设置一些变量……但它不起作用。如果您考虑扩展您的答案,我会再次投票。 如果您在 nginx 配置中使用 passenger_env_var 命令,则环境变量将由乘客设置,因此您的 Rails 应用程序可以访问。看我的回答。【参考方案5】:

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

服务器 server_name www.foo.com; 根/webapps/foo/public; 乘客启用; 乘客env_var DATABASE_USERNAME foo_db; 乘客 env_var DATABASE_PASSWORD 秘密; 乘客 env_var SECRET_KEY_BASE the_secret_keybase;

这对我有用。请联系 phusion 乘客 docs 了解更多信息。

【讨论】:

没有为我做任何事情,仍然显示我没有使用 mysql2 的密码,如果我将 替换为我的密码,应用程序就可以正常工作. 你用的是什么版本的nginx? passenger_env_var 在版本 5.0.0 中添加。以前的版本不支持它。 root@server:~#passenger-config --version Phusion Passenger 5.0.30 我最终不得不编辑我的 RVM 包管理器的环境配置文件以包含用户的 .bashrc 文件 这可行,但您需要记住,变量将由乘客访问。执行本地操作(rake assets:precompile 等)将无法获取它们【参考方案6】:

我在/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" "$@"

【讨论】:

【参考方案7】:

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

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

【讨论】:

【参考方案8】:

已编辑:

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

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

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

如果你在本地计算机上使用 Nginx 作为服务器,你可以在你的 nginx 配置文件中定义你的环境变量。

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

【讨论】:

【参考方案9】:

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

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

【讨论】:

【参考方案10】:

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

file: $rvm_path/environments/default

要查找路径,请运行以下命令:

ls -lah `whereis rvm`/environments/default

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

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

【讨论】:

【参考方案11】:

保存项目环境变量的最佳位置是 /etc/profile.d/YOUR_FILE.sh, Here 您可以找到文档,该文档详细说明了在何处保留不同场景的 env 变量。

【讨论】:

【参考方案12】:

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

总结:

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

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

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

【讨论】:

【参考方案13】:

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

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

【讨论】:

当 rc.d 脚本启动 nginx 时,重启后是否会登录?

以上是关于在 Ubuntu 上使用 nginx 和Passenger 时在哪里放置环境变量的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ubuntu 14.04 上使用 nginx 和 gunicorn 部署 django 1.8 应用程序

在 Ubuntu 上使用 Nginx 部署 Flask 应用

如何在 Ubuntu 上同时运行 nginx 和 Apache?

如何在 Ubuntu 上使用 pm2 和 Nginx 部署 Node.js 应用

如何使用Nginx和uWSGI或Gunicorn在Ubuntu上部署Flask Web应用

如何在 Ubuntu上使用 Nginx 设置密码验证