supervisor child process not reading environment variable - linux

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

Related

How to run two shell scripts at startup?

I am working with Ubuntu 16.04 and I have two shell scripts:
run_roscore.sh : This one fires up a roscore in one terminal.
run_detection_node.sh : This one starts an object detection node in another terminal and should start up once run_roscore.sh has initialized the roscore.
I need both the scripts to execute as soon as the system boots up.
I made both scripts executable and then added the following command to cron:
#reboot /path/to/run_roscore.sh; /path/to/run_detection_node.sh, but it is not running.
I have also tried adding both scripts to the Startup Applications using this command for roscore: sh /path/to/run_roscore.sh and following command for detection node: sh /path/to/run_detection_node.sh. And it still does not work.
How do I get these scripts to run?
EDIT: I used the following command to see the system log for the CRON process: grep CRON /var/log/syslog and got the following output:
CRON[570]: (CRON) info (No MTA installed, discarding output).
So I installed MTA and then systemlog shows:
CRON[597]: (nvidia) CMD (/path/to/run_roscore.sh; /path/to/run_detection_node.sh)
I am still not able to see the output (which is supposed to be a camera stream with detections, as I see it when I run the scripts directly in a terminal). How should I proceed?
Since I got this working eventually, I am gonna answer my own question here.
I did the following steps to get the script running from startup:
Changed the type of the script from shell to bash (extension .bash).
Changed the shebang statement to be #!/bin/bash.
In Startup Applications, give the command bash path/to/script to run the script.
Basically when I changed the shell type from sh to bash, the script starts running as soon as the system boots up.
Note, in case this helps someone: My intention to have run_roscore.bash as a separate script was to run roscore as a background process. One can run it directly from a single script (which is also running the detection node) by having roscore& as a command before the rosnode starts. This command will fire up the master as a background process and leave the same terminal open for following commands to be executed.
If you could install immortal you could use the require option to start in sequence your services, for example, this is could be the run config for /etc/immortal/script1.yml:
cmd: /path/to/script1
log:
file: /var/log/script1.log
wait: 1
require:
- script2
And for /etc/immortal/script2.yml
cmd: /path/to/script2
log:
file: /var/log/script2.log
What this will do it will try to start both scripts on boot time, the first one script1 will wait 1 second before starting and also wait for script2 to be up and running, see more about the wait and require option here: https://immortal.run/post/immortal/
Based on your operating system you will need to configure/setup immortaldir, her is how to do it for Linux: https://immortal.run/post/how-to-install/
Going more deep in the topic of supervisors there are more alternatives here you could find some: https://en.wikipedia.org/wiki/Process_supervision
If you want to make sure that "Roscore" (whatever it is) gets started when your Ubuntu starts up then you should start it as a service (not via cron).
See this question/answer.

How to use pm2 with a nodejs app that uses readline for taking command line input?

I have a Node.js app that uses the node's native readline to be able to take command-line inputs.
When launching the app with pm2, the command-line input is unavailable.
Any ideas how to solve this issue? Other than using systemd and creating an init script myself?
Use pm2 to attach to your process and you will see readline, clearline and cursorTo working as expected.
First get your process id with:
$ pm2 id {your-process-name}
[ 7 ]
Let's say it's 7:
$ pm2 attach 7
if you check the pm2 website they clearly mention the following line: Advanced, production process manager for Node.js. So using it in this context is unnecessary as all pm2 does is start your 'node' process and allows you to manage it, the simple way is to use command line args while starting the process.
for example:
I myself use commander for this purpose. it manages all my command line arguments (u can see its usage). and with pm2 i use it like following:
pm2 start server.js --name production -- --env dev -p 3458
notice -- before --env, it is used to separate pm2 arguments from the arguments you want to supply to your process
p.s.
PM2 has more complex usage than this, in the terms of process management, i myself use it for production level deployment. If you want to take input from a user every time s/he starts your app, then you should stick with using node command only

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.

Supervisor doesn't recognize environment variable in Nodejs

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

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