【问题标题】:Upstart env stanza not setting environment variables (like NODE_ENV) for Node.js applicationUpstart env 节没有为 Node.js 应用程序设置环境变量(如 NODE_ENV)
【发布时间】: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(保留环境)可以尝试,虽然我自己没有测试过。

标签: node.js ubuntu environment-variables upstart


【解决方案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 脚本中使用 susudo 的一个令人沮丧的方面。最新版本的新贵支持在不使用 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 而不是 susudo

    但是,除非您仍在使用只有 Upstart 版本 0.6.5 的 10.04 LTS (Lucid Lynx),否则您应该使用 setuid/setgid 指令。

    【讨论】:

    • 这不完全正确(还有吗?)从 Upstart 1.4 开始,Upstart 能够使用 setuidsetgid 节以指定用户身份运行系统作业。
    • 我知道这一点,谢谢。但你让我意识到答案可能不够清楚。
    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 2016-03-20
      • 2013-10-29
      • 1970-01-01
      • 2016-10-08
      • 2014-08-02
      • 2020-01-01
      • 1970-01-01
      • 2021-05-27
      • 2020-10-30
      相关资源
      最近更新 更多