Upstart env 节没有为 Node.js 应用程序设置环境变量(如 NODE_ENV)
Posted
技术标签:
【中文标题】Upstart env 节没有为 Node.js 应用程序设置环境变量(如 NODE_ENV)【英文标题】:Upstart env stanza not setting environment variables (like NODE_ENV) for Node.js application 【发布时间】:2012-02-12 17:49:33 【问题描述】:我的服务器有一个 Upstart 脚本,如下所示:
description "myapp node.js server"
start on runlevel [2345]
stop on shutdown
env NODE_ENV=production
env CUSTOM=somevalue
exec sudo -u nodejs /usr/local/bin/node /opt/myapp/app.js >> /var/log/nodejs/myapp.log 2>&1
post-start script
NODE_PID=`status myapp | egrep -oi '([0-9]+)$' | head -n1`
echo $NODE_PID > /var/run/nodejs/myapp.pid
end script
但是,该应用没有看到 NODE_ENV 设置为生产。事实上,如果我在应用程序中使用 console.log(process.env),我看不到 NODE_ENV 或 CUSTOM。有什么想法吗?
顺便说一句,NODE_ENV=production node app.js 工作正常。
【问题讨论】:
彼得莱昂斯的回答深入探讨并提供了一些最佳实践建议,但如果我切换到使用“www-data”用户与我自己的“nodejs”用户。后者还不起作用,但这与这个问题有些无关。 我还要提一下,sudo -E(保留环境)可以尝试,虽然我自己没有测试过。 【参考方案1】:visudo
有一行定义要保留的环境变量。
sudo visudo
并将您的环境添加到:
Defaults env_keep="YOUR_ENV ..."
然后重启。
【讨论】:
【参考方案2】:来自sudo man page(Ubuntu 版本的 sudo)
有两种不同的方式来处理环境变量。默认情况下, env_reset sudoers 选项已启用。这会导致在包含 TERM 的最小环境中执行命令, PATH、HOME、SHELL、LOGNAME、USER 和 USERNAME 以及来自调用过程的变量 env_check 和 env_keep sudoers 选项允许。实际上有一个白名单 环境变量。
Sudo 正在重置环境。这是在 upstart 或 init 脚本中使用 su
和 sudo
的一个令人沮丧的方面。最新版本的新贵支持在不使用 sudo 的情况下通过 setuid/setgid
指令指定 uid/gid,如下例所示。还要注意chdir
的使用。
start on filesystem and started networking
respawn
chdir /var/www/yourapp
setuid yourapp
setgid yourapp
env NODE_ENV=production
env PATH=/usr/local/bin:/usr/bin:/bin
env CUSTOM=somevalue
exec /usr/local/bin/node app.js | /usr/bin/multilog s1024000 /var/log/yourapp 2>&1
对于旧版本的暴发户,这是我用来解决它的方法。
description "start and stop the example.com node.js server"
start on filesystem and started networking
respawn
chdir /path/to/your/code
exec su -c 'PATH=$PWD/node/bin NODE_ENV=$(cat node_env.txt) ./node/bin/node app/server.js' www-data >> tmp/stdout.log 2>&1
请注意,我只是在我的应用根目录中放置了一个 node_env.txt
文件来设置生产模式,因为 I hate environment variables。如果您愿意,可以直接在此处输入NODE_ENV=production
。
【讨论】:
几个问题:(1)node_env.txt 里有什么,只是“生产”? (2) 为什么将 PATH 设置为 $PWD/node/bin?并使用./node/bin/node。您是否为您的应用程序安装了本地节点? (3) 为什么使用 su -c 与 sudo -u?谢谢。 node_env.txt 仅包含单个单词“production”(带有尾随换行符)。就这样。是的,我在我的应用程序根目录中安装了节点,我认为这是最佳实践。我在同一台服务器上有许多应用程序,每个应用程序都需要不同的节点版本。我从不共享我的应用服务器堆栈的版本。您应该在 upstart 脚本中使用“su”而不是 sudo,因为它们已经由操作系统以 root 身份运行,并且您不需要 sudo。 “su”在这里是合适的 - 成为不同的用户。 “sudo”更多的是让普通用户以root身份执行特定命令,此处不适用 我将代码切换为使用 exec su -c '...' nodejs >> ... 我现在无法启动该过程。如果我在 shell 中手动运行该命令,系统会要求我输入密码。我用用户 www-data 尝试了手动命令,它要求输入密码。然后我 sudo su -c ... 使用 www-data 并且它起作用了。我还没有尝试在我的 Upstart 脚本中使用 www-data。关于 Linux 用户配置,我在这里缺少什么? 如果您以非 root 身份执行su
,这就是它的工作原理。以root身份运行它,它不会提示输入密码。因此,要从 shell 进行交互式测试,首先执行“sudo su -”成为 root,然后运行 su
命令,就像它在你的 upstart 文件中一样。
我不同意“环境变量是有害的”。它们在代码开发和服务器部署配置之间提供了一个可靠的接口。当与适当的 devops 策略(如 chef)结合使用时,可以在所有正确的位置可靠地设置环境变量 - 使部署可以轻松更改配置,而无需在源代码文件夹中四处寻找。【参考方案3】:
仅作记录。当您的 Upstart 版本不实现 setuid
时,Upstart Cookbook 建议使用 the usage of start-stop-daemon
而不是 su
或 sudo
。
但是,除非您仍在使用只有 Upstart 版本 0.6.5 的 10.04 LTS
(Lucid Lynx),否则您应该使用 setuid/setgid
指令。
【讨论】:
这不完全正确(还有吗?)从 Upstart 1.4 开始,Upstart 能够使用setuid
和 setgid
节以指定用户身份运行系统作业。
我知道这一点,谢谢。但你让我意识到答案可能不够清楚。【参考方案4】:
这一直对我在新贵中设置节点环境变量有用。
#!upstart
start on runlevel [2345]
stop on runlevel [016]
respawn
script
echo $$ > /var/run/app.pid
exec sudo NODE_ENV=production /opt/node/bin/node /opt/myapp/app.js >> /var/log/app.sys.log 2>&1
end script
【讨论】:
以上是关于Upstart env 节没有为 Node.js 应用程序设置环境变量(如 NODE_ENV)的主要内容,如果未能解决你的问题,请参考以下文章
Node.js里面怎么设置process.env.PORT的值
如何使用 Amazon EC2 实例为生产设置 node.js process.env 变量?
Node.JS 错误 - process.env.NODE_TLS_REJECT_UNAUTHORIZED。这是啥意思?