Supervisor doesn't recognize environment variable in Nodejs - node.js

This is my supervisor setting for a NodeJS API, but the NODE_ENV variable doesn't get recognized. API works in Default mode right now. But I want it to run it in NODE_ENV development
[program:api]
command=/usr/bin/node /srv/apps/api/src/index.js
directory=/srv/apps/api
autostart=true
autorestart=true
startretries=3
stderr_logfile=/srv/logs/api/error.log
stdout_logfile=/srv/logs/api/out.log
user=api-user
environment= NODE_ENV="development"
Any ideas?

It seems that after typing supervisorctl reread you should also use supervisorctl update

Related

supervisor child process not reading environment variable

In my go program, I'm using os.Getenv("DB_PASSWORD") to grab the environment variable DB_PASSWORD.
While in development, I use godotenv and GNU Make to build and start the program. In production, I'm using supervisor to manage the process (basically for its daemonizing and auto-restart capabilities).
But with supervisor, my go program is unable to access any environment variables (set using export key='value').
I've checked out supervisor with environment variables section and it's still not working.
I've done supervisorctl reread and supervisorctl update, still no luck.
How can I get supervisor child process (my program) to read environment variables
[program:program_name]
command=/var/www/program_name/bin/program_name -environment production -port 4041 --DB_PASSWORD=%(ENV_DB_PASSWORD)s
directory=/var/www/program_name
environment=DB_PASSWORD=value-here
autorestart=true
autostart=true
stdout_logfile=/var/www/program_name/logs/supervisord.log
stderr_logfile=/var/www/program_name/logs/supervisord_err.log
stdout_logfile_maxbytes=5MB
stderr_logfile_maxbytes=5MB
logfile_backups=3
loglevel=info

npm adds whitespace when setting env variable in package.json

I have a pre-written package.json file for an app which I need to modify. More specifically, I want to change the NODE_PORT environment variable through the package.json file and I'm working on a Windows machine.
In the package.json I have several scripts that I run through npm when I like to spin up an instance of the app.
For example:
set NODE_PORT=80&& set NODE_ENV=test&& pm2 install pm2-logrotate&& pm2 start app.js -i max -o ./logs/access.log -e ./logs/err.log --time --name Test
This script for example works fine.
However, when I'm trying to set the NODE_PORT variable to 8080 (that's the port I need) like so:
set NODE_PORT=8080&& set NODE_ENV=parallel_test&& pm2 install pm2-logrotate&& pm2 start app.js -i max -o ./logs/parallel_access.log -e ./logs/parallel_err.log --time --name Parallel_Test
a whitespace at the end of the variable gets added.
I verified this by printing out the number of chars of $process.env.NODE_PORT in the log file which prints 5. Moreover the login for the app via Google crashes as the redirect link of the app doesn't match with the one in the Google Cloud Platform. That is:
app: http://localhost:8080 /auth/check-google vs. Google Cloud Platform: http://localhost:8080/auth/check-google
Any idea why this is happening?
i have faced similar issue recently. Handled it with .trimEnd() while adding variables with dotenv. But I think using cross-env can solve your problems.
Most Windows command prompts will choke when you set environment
variables with NODE_ENV=production like that. (The exception is Bash
on Windows, which uses native Bash.) Similarly, there's a difference
in how windows and POSIX commands utilize environment variables. With
POSIX, you use: $ENV_VAR and on windows you use %ENV_VAR%.
Adding this inside your script: "cross-env NODE_PORT=8080 ..."

Docker & PM2: String based CMD with environment variables

I'm currently using the shell-form of CMD in Docker for launching my node app:
CMD /usr/src/app/node_modules/.bin/trifid --config $TRIFID_CONFIG
The env-var TRIFID_CONFIGis set to a default in the Dockerfile:
ENV TRIFID_CONFIG config.customer.json
This makes it easy to pass another config file for dev-environments for example.
Now I try to switch this to PM2 for production. However it looks like all PM2 samples are using the "exec" form which from what I understood does not evaluate ENV-vars. I tried the shell-form with PM2:
CMD pm2-docker /usr/src/app/node_modules/trifid/server.js --config $TRIFID_CONFIG
But it looks like the variable is not evaluated like this, it fails back to default on execution.
What would be the proper way to handle this with PM2 inside a Docker image?
I had a discussion on Github and meanwhile figured it out:
CMD pm2-docker /usr/src/app/node_modules/.bin/trifid -- --config $TRIFID_CONFIG
So the trick is to use -- after the command and the rest will be passed as argument. If I use the shell form env-vars do seem to get evaluated properly.

Environment variable with period in using supervisor started node process

I have a node process that uses an environment variable in the form SECRET_KEY=1234.5678.910112.
This works fine if set using export in my bash_profile and the process is run directly in the shell.
But when running it using supervisor the script only picks up the part before the first period. This is the case either when reading env vars set in bash_profile or set using environment= in the conf file.
Turns out all I needed to do was to add single quotes around my variable. I did do this before but didn't run supervisorctl reread to get the new config.

Nodejs/Strongloop: working upstart config example

After update strongloop to v2.10 slc stops writing logs.
Also I couldn't make the app to start in production mode.
/etc/init/app.conf
#!upstart
description "StrongLoop app"
start on startup
stop on shutdown
env NODE_ENV=production
script
exec slc run /home/ubuntu/app/ \
-l /home/ubuntu/app/app.log \
-p /var/run/app.pid
end script
Can anybody check my upstart config or provide another working copy?
Are you were writing the pid to a file so that you can use it to send SIGUSR2 to the process to trigger log re-opening from logrotate?
Assuming you are using Upstart 1.4+ (Ubuntu 12.04 or newer), then you would be better off letting slc run log to its stdout and let Upstart take care of writing it to a file so that log rotation is done for you:
#!upstart
description "StrongLoop app"
start on startup
stop on shutdown
# assuming this is /etc/init/app.conf,
# stdout+stderr logged to: /var/log/upstart/app.log
console log
env NODE_ENV=production
exec /usr/local/bin/slc run --cluster=CPUs /home/ubuntu/app
The log rotation for "free" is nice, but the biggest benefit to this approach is Upstart can log errors that slc run reports even if they are a crash while trying to set up its internal logging, which makes debugging a lot easier.
Aside from what it means to your actual application, the only effect NODE_ENV has on slc run is to set the default number of cluster workers to the number of detected CPU cores, which literally translates to --cluster=CPUs.
Another problem I find is the node/npm path prefix not being in the $PATH as used by Upstart, so I normally put the full paths for executables in my Upstart jobs.
Service Installer
You could also try using strong-service-install, which is a module used by slc pm-install to install strong-pm as an OS service:
$ npm install -g strong-service-install
$ sudo sl-svc-install --name app --user ubuntu --cwd /home/ubuntu/app -- slc run --cluster=CPUs .
Note the spaces around the -- before slc run

Resources