Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Upstart env stanza not setting environment variables (like NODE_ENV) for Node.js application

I have an Upstart script for my server that looks like this:

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 

However, the app doesn't see NODE_ENV set to production. In fact, if I console.log(process.env) within the app, I don't see NODE_ENV or CUSTOM. Any ideas what's happening?

By the way, NODE_ENV=production node app.js works just fine.

like image 978
Chris F Avatar asked Jan 17 '12 22:01

Chris F


People also ask

What is NODE_ENV in node JS?

NODE_ENV is an environment variable that stands for node environment in express server. The NODE_ENV environment variable specifies the environment in which an application is running (usually, development or production).

What is process env NODE_ENV === development?

process. env is a reference to your environment, so you have to set the variable there. To set an environment variable in Windows: SET NODE_ENV=development. on macOS / OS X or Linux: export NODE_ENV=development. Follow this answer to receive notifications.

Does jest set NODE_ENV?

Jest automatically defines environment variable NODE_ENV as test (see https://jestjs.io/docs/environment-variables), as you can confirm from your error message: console.


2 Answers

From the sudo man page (Ubuntu version of sudo)

There are two distinct ways to deal with environment variables. By default, the env_reset sudoers option is enabled. This causes commands to be executed with a minimal environment containing TERM, PATH, HOME, SHELL, LOGNAME, USER and USERNAME in addition to variables from the invoking process permitted by the env_check and env_keep sudoers options. There is effectively a whitelist for environment variables.

Sudo is resetting the environment. This is a frustrating aspect of using su and sudo in upstart or init scripts. Recent versions of upstart support specifying uid/gid without the use of sudo via the setuid/setgid directives as in the example below. Also note the use of 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 

For older versions of upstart, here's what I used to do to work around it.

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 

Note that I just put a node_env.txt file in my app root that sets production mode, because I hate environment variables. You can just do NODE_ENV=production right there if you prefer.

like image 52
Peter Lyons Avatar answered Sep 30 '22 16:09

Peter Lyons


Just for the record. The Upstart Cookbook recommends the usage of start-stop-daemon instead of su or sudo when your Upstart version does not implement setuid.

But, unless you are still using 10.04 LTS (Lucid Lynx) which only has Upstart version 0.6.5, you should be using the setuid/setgid directives.

like image 31
C2H5OH Avatar answered Sep 30 '22 16:09

C2H5OH