在 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
中将这些变量添加为export
s,以便在系统重新启动时自动设置这些变量?
我不确定每个文件何时被读入。
【问题讨论】:
【参考方案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 指出的那样,当一个 sudo
s 成为 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
命令的应用程序的服务器定义中:
这对我有用。请联系 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 应用