config file for upstart with nodejs - node.js

Can you advise a upstart config file for nodejs on ubuntu? I've found the follows tutorial: http://howtonode.org/deploying-node-upstart-monit but it seem very old.

I have a little shell script that creates my config files.
create_upstart() {
project=$1
file=$2
conf="/etc/init/${project}_${file}.conf"
cat > $conf << EOF
#!upstart
description "Node Process - $1"
author "Geert Pasteels"
respawn
start on (local-filesystems and net-device-up IFACE=eth0)
stop on shutdown
script
export NODE_ENV="production"
export PORT="3001"
exec /usr/bin/node /var/www/$project/current/$file.js >> /var/www/$project/shared/logs/$file 2>&1
end script
EOF
echo $conf
# Restart upstart script
stop ${project}_${file}
start ${project}_${file}
echo Restarted ${project}_${file}
}
create_upstart "$1" "$2"
I use this in combination with TJ's deploy. So in my post deploy hook i do startup app file.

Related

Ubuntu run script as non-root user

I've an init script (/etc/init.d) that should run a my executable jar file as a serviceat boot. I need that this script is runned by a specified user.
With su & sudo is possibile but it split the process and I don't like this.
There is another way to run this script as limited user?
This is the relevant part of my init script:
#!/bin/bash
APP_NAME="myapp"
APP_HOME=/home/user1/jetty
JAVA_HOME=/opt/local/java/latest
echo "Service $APP_NAME - [$1]"
echo "JAVA_HOME -> $JAVA_HOME"
echo "APP_HOME -> $APP_HOME"
echo "APP_NAME -> $APP_NAME"
function start {
if pkill -0 -f $APP_NAME.jar > /dev/null 2>&1
then
echo "Service [$APP_NAME] is already running. Ignoring startup request."
exit 1
fi
echo "Starting application..."
cd $APP_HOME
nohup $JAVA_HOME/bin/java -jar $APP_HOME/$APP_NAME.jar\
< /dev/null > $APP_HOME/logs/app.log 2>&1 &
}
On Ubuntu you should use the program start-stop-daemon for this. It has options for launching daemons as different users, managing pid files, changing the working directory, and pretty much anything else that is usually needed by init scripts.

To run node.js in system boot

I have written an API using node.js. I have deployed it in the production environment. Now i ran the program(server.js) using forever.js, its working fine
But i want my node to run when the system boots itself.
I tried by creating a file in \etc\init api.conf with the following content.
start on startup
exec forever start /home/testuser/server.js
But when i reboot my system the above isn't running.Please help me solve this.
Thanks in advance.
EDIT:
Finally i tried this:
# Source function library.
. /lib/lsb/init-functions
NODE_ENV="production"
PORT="2100"
APP_DIR="/home/testuser/API/"
NODE_APP="server.js"
CONFIG_DIR="$APP_DIR"
PID_DIR="$APP_DIR/pid"
PID_FILE="$PID_DIR/server.pid"
LOG_DIR="/home/testuser/APIlogs/"
LOG_FILE="$LOG_DIR/project-debug.log"
NODE_EXEC=$(which node)
pidFile="$PID_DIR/server.pid"
logFile="$LOG_DIR/project-debug.log"
sourceDir=/home/testuser/API
coffeeFile=server.js
scriptId=$sourceDir/$coffeeFile
start() {
echo "Starting $scriptId"
# This is found in the library referenced at the top of the script
start_daemon
# Start our CoffeeScript app through forever
# Notice that we change the PATH because on reboot
# the PATH does not include the path to node.
# Launching forever or coffee with a full path
# does not work unless we set the PATH.
cd $sourceDir
PATH=/usr/local/bin:$PATH
forever start /home/testuser/API/server.js
RETVAL=$?
}
restart() {
echo -n "Restarting $scriptId"
/usr/local/bin/forever restart $scriptId
RETVAL=$?
}
stop() {
echo -n "Shutting down $scriptId"
/usr/local/bin/forever stop $scriptId
RETVAL=$?
}
status() {
echo -n "Status $scriptId"
/usr/local/bin/forever list
RETVAL=$?
}
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status
;;
restart)
restart
;;
*)
echo "Usage: {start|stop|status|restart}"
exit 1
;;
esac
exit $RETVAL
When i tried the following command:
/etc/init.d/API start it works fine. When i reboot the system it says "NO forever process" running.
You should have a look at Upstart. People use it with Node. Forever is good just for testing.
I suggest switching to pm2.
$ npm install pm2 -g
$ pm2 start /home/testuser/server.js
$ pm2 list
PM2 can generate and configure a startup script to keep PM2 and your processes alive at every server restart.
$ pm2 startup ubuntu
To save a process list just do:
$ pm2 save
You check here for more information about setting-up pm2 on a Ubuntu server for production.

UPSTART script non root not working

I'm trying to run a nodejs application using upstart as a non root user.
But somehow parts of the script will not run : for instance:
if I run it like a root user(below example) NODE_ENV never gets called/set
the only way to called is with "sudo initctl stop pdcapp"
sudo nameofApp start|stop would not work
When called sudo initctl stop nameofApp the pre-stop script will not echo to the log file
if I try to runit like a non root user it would not even start
isn't a more cleaner easier way of doing this (systemd) I've looked a various tutorials around and apparently this is how they've doneit. so what am I missing here?
This is the .conf file under /etc/init/
env FULL_PATH="/srv/pd/sept011100/dev"
env NODE_PATH="/usr/local/nodeJS/bin/node"
env NODE_ENV=production
start on filesystem or runlevel [2345]
stop on [!2345]
script
export NODE_ENV #this variable is never set
echo $$ > /var/run/PD.pid
cd $FULL_PATH
# the command below will not work
#exec sudo -u nginx "$NODE_PATH server.js >> /var/log/PD/pdapp.log 2>&1"
exec $NODE_PATH server.js >> /var/log/PD/pdapp.log 2>&1
end script
pre-start script
echo "[`date`] (sys) Starting" >> /var/log/PD/pdapp.log
end script
pre-stop script
rm /var/run/pdapp.pid
echo "[`date`] (sys) Stopping" >> /var/log/PDC/pdapp.log
end script
in /var/log/messages I get this when I stop the application, otherwise I get nothing in the logfile
Sep 2 18:23:14 547610-redhat-dev2 init: pdcapp pre-stop process (6903) terminated with status 1
Sep 2 18:23:14 547610-redhat-dev2 init: pdcapp main process (6899) terminated with status 143
any Ideas why is this not working I'm running redhat 6.5
Red Hat has a super old version of Upstart that is probably full of bugs because they never contributed to Upstart, despite using it (Fedora switched to systemd right after RHEL 6 was released, before they even really tried it out well).

Upstart node.js working directory

Starting Node.js with Upstart, when trying to access files within Node.js it cannot access them without using the full path. I need it to use the working directory.
start on startup
stop on shutdown
script
echo $$ > /var/run/mynodeapp.pid
exec sudo -u mynodeapp node server.js >> /var/log/mynodeapp.sys.log 2>&1
end script
pre-start script
echo "Starting" >> /var/log/mynodeapp.sys.log
end script
pre-stop script
rm /var/run/mynodeapp.pid
echo "Stopping" >> /var/log/mynodeapp.sys.log
end script
The solution is to change directory within the script. In my case, the user is mynodeapp and the node files are in the users directory (/home/mynodeapp/).
script
chdir /home/mynodeapp/
echo $$ > /var/run/mynodeapp.pid
exec sudo -u mynodeapp node server.js >> /var/log/mynodeapp.sys.log 2>&1
end script
I have yet to find out what $$ means on the echo line or 2>&1. Maybe somebody could chime in with this if they know!
You should use the chdir stanza as per the Upstart docs: http://upstart.ubuntu.com/cookbook/#chdir

Upstart script for node.js app

I'm having trouble starting an Upstart script.
Here's the script (app.conf in /etc/init/)
description "node.js server"
author "kvz"
start on startup
stop on shutdown
script
# We found $HOME is needed. Without it, we ran into problems
export HOME="/root"
exec sudo -u /usr/local/bin/node \
/var/www/vhosts/travelseguro.com/node/app.js \
2>&1 >> /var/log/node.log
end script
When I run sudo start app, I get:
start: Unknown job: app
How can I make this work?
I was having the same problem running on the latest Amazon (AWS) linux which is Redhat based.
I have my upstart file in /etc/init called node.conf and when I ran sudo start node I would get a similar error to you start: Unknown job: node.
It turns out that the job won't start if there's an error in your .conf file. So I started out by commenting out all the lines and slowly building up to find the error. The error message isn't very clear and makes it look like upstart can't find your conf file.
Tailing your '/var/log/messages' will help you debug as Upstart logs to there (It may be somewhere different on Ubuntu. Mine said init: /etc/init/node-upstart.conf:8: Unknown stanza which helped me get to the bottom of it. In my particular case I was declaring variables incorrectly.
See on AskUbuntu for a similar thread.
Here's my edited working script:
<!-- language: lang-sh -->
#!upstart
# using upstart http://upstart.ubuntu.com/getting-started.html and node forever https://github.com/nodejitsu/forever/
# to run server
# redhat has additional sudo restrictions, you must comment out 'Default requiretty' from /etc/sudoers
#startup monitoring script derived from http://stackoverflow.com/questions/11084279/node-js-setup-for-easy-deployment-and-updating
description "node.js server"
author "jujhar"
env PROGRAM_NAME="node"
env FULL_PATH="/home/httpd/buto-middleman/public"
env FILE_NAME="forever.js"
env NODE_PATH="/usr/local/bin/node"
env USERNAME="springloops"
start on startup
stop on shutdown
script
export HOME="/root"
export NODE_ENV=staging #development/staging/production
echo $$ > /var/run/$PROGRAM_NAME.pid
cd $FULL_PATH
#exec sudo -u $USERNAME $NODE_PATH $FULL_PATH/$FILE_NAME >> /var/log/$PROGRAM_NAME.sys.log 2>&1
exec $NODE_PATH $FULL_PATH/$FILE_NAME >> /var/log/$PROGRAM_NAME.sys.log 2>&1
end script
pre-start script
# Date format same as (new Date()).toISOString() for consistency
echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (sys) Starting" >> /var/log/$PROGRAM_NAME.sys.log
end script
pre-stop script
rm /var/run/$PROGRAM_NAME.pid
echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (sys) Stopping" >> /var/log/$PROGRAM_NAME.sys.log
end script
-- Edit 2013-06-01 --
If you're on Centos or Amazon Linux like me, take a look at this init.d script.
-- Edit 2013-10-14 --
Here's a link to a gist of an init.d script that I actually use in production on Amazon Linux(Redhat Based). I simply keep it in my project under an init.d folder and then symlink to it in the /etc/init.d folder and now it's a daemon/service!
-- Edit 2014-06-05 --
Check out this awesome blog artcile by Jeff Dickey on Node.js in production using systemd which is much cleaner and easier than all the stuff we've been doing here (IMHO). He also uses Ansible to control his cluster (which I love) but you don't have to go that far if you're not ready.
After a few attempts I implemented working .conf file for upstart which works as a service with automatic start after reboot and restart (respawn) in case of crash. Also it can start my app with unprivileged user permissions. The name of the file is /etc/init/my-app.conf.
To start / stop service please use
sudo start my-app / sudo stop my-app
If you have an error like
start: Unknown job: my-app
exec the following command
sudo initctl reload-configuration
My /etc/init/my-app.conf file:
#my-app
description "node.js my-app website"
env FULL_PATH="/home/myuser/app.prod/app"
env NODE_PATH="/usr/bin/node"
start on filesystem or runlevel [2345]
stop on [!2345]
script
export HOME="/root"
export NODE_ENV=production
echo $$ > /var/run/my-app.pid
cd $FULL_PATH
#Use exec below if you want to launch it under myuser,
#don't forget to create /var/log/my-app.sys.log with appropriate permissions
#exec sudo -u myuser sh -c "$NODE_PATH server.js >> /var/log/my-app.sys.log 2>&1"
exec $NODE_PATH server.js >> /var/log/my-app.sys.log 2>&1
end script
pre-start script
echo "[`date`] (sys) Starting" >> /var/log/my-app.sys.log
end script
pre-stop script
rm /var/run/my-app.pid
echo "[`date`] (sys) Stopping" >> /var/log/my-app.sys.log
end script
#uncomment respawn if you want to restart your service in case of crash
#respawn
#respawn limit 50 30
I do recommend to uncomment respawn after you will make sure that everything works ok.
UPDATE
I improved my script (please keep in mind that it works not under root but under regular user zn ):
#znapi.conf
description "node.js zn api"
env FULL_PATH="/home/zn/app.prod"
env NODE_PATH="/usr/bin/node"
env LOG="/var/log/znapi.log"
env PIDFILE="/var/run/znapi.pid"
# Start up when the system hits any normal runlevel, and
#start on filesystem or runlevel [2345]
#start when mongod started
start on started mongod
# shuts down when the system goes to shutdown or reboot.
stop on runlevel [06]
respawn
respawn limit 50 5
pre-start script
# check that log file exist or create it
test -f $LOG || { touch $LOG; chown zn:zn $LOG; }
# Date format same as (new Date()).toISOString() for consistency
echo "[`date`] (sys) Starting" >> $LOG
end script
script
export NODE_ENV=production
exec start-stop-daemon --start -m -p $PIDFILE -c zn -d $FULL_PATH -x server.js >> $LOG 2>&1
end script
pre-stop script
rm $PIDFILE
echo "[`date`] (sys) Stopping" >> $LOG
end script

Resources