14

I'm working on a Raspberry Pi running Raspbian running a Node.js app and trying to get it to start when the Pi boots. I found a couple of examples but I can't seem to get it working. My current code is:

#! /bin/sh
# /etc/init.d/MyApp

### BEGIN INIT INFO
# Provides:          MyApp.js
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Starts MyApp.js
# Description:       Start / stop MyApp.js at boot / shutdown.
### END INIT INFO

# If you want a command to always run, put it here

# Carry out specific functions when asked to by the system
case "$1" in
   start)
    echo "Starting MyApp.js"
    # run application you want to start
    node /home/pi/app/MyApp/MyApp.js
   ;;
   stop)
    echo "Stopping MyApp.js"
    # kill application you want to stop
    killall MyApp.js
    ;;
  *)
    echo "Usage: /etc/init.d/MyApp {start|stop}"
    exit 1
    ;;
esac

exit 0

I have this in the etc/init.d folder, ran chmod +x /etc/init.d/MyApp, I'm able to run it manually, then I run sudo update-rc.d MyApp defaults, reboot and the script never runs. I've looked at some different examples, made adjustments and still no luck.

halfer
  • 19,824
  • 17
  • 99
  • 186
user2650875
  • 165
  • 1
  • 1
  • 6

3 Answers3

32

I solved this problem by first checking where node.js was installed on RaspberryPi:

which node

This gave me :

/usr/local/bin/node

Open crontab config:

sudo crontab -e

Then in my crontab :

@reboot sudo /usr/local/bin/node <complete path to your .js app> &

Save, reboot, and problem solved !

Garth
  • 3,237
  • 2
  • 18
  • 28
Mohit Athwani
  • 883
  • 9
  • 17
11

Mohit is right, but just for clarification, you can use readlink to find the full path for your Node.js app as it will be needed later to add as a cron job.

readlink -f <<name of file >>

For instance readlink -f HAP-NodeJS/Core.js results in /home/pi/HAP-NodeJS/Core.js

You can also use which node to find the full path where node.js is installed

Next, create a new cron job using sudo crontab -e and add the following code at the very end:

@reboot sudo /usr/local/bin/node <<.js application path>> &

for instance, my code looks like this.

@reboot sudo /usr/local/bin/node /home/pi/HAP-NodeJS/Core.js &

Upon reboot (or start up) , your Node.js should run. Hope this clears things.

Adeel C
  • 111
  • 1
  • 2
4

If you're using a prebuilt Pi release like 0.10.24, you may be experiencing a PATH issue.

You can either provide the full path to the node binary as part of the start command or make sure the PATH to the node binaries are set before /etc/init.d/MyApp is ran. I had the same issue and tried both with success. Also, the stop command as you have it may not be working.

#! /bin/sh
# /etc/init.d/test

### BEGIN INIT INFO
# Provides:          test
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Example initscript
# Description:       This file should be used to construct scripts to be
#                    placed in /etc/init.d.
### END INIT INFO

# Carry out specific functions when asked to by the system
case "$1" in
   start)
    echo "Starting test.js"
    # run application you want to start
    #node /home/pi/test.js > /home/pi/test.log
    /home/pi/downloads/node-v0.10.24-linux-arm-pi/bin/node /home/pi/test.js >> /home/pi/test.log
   ;;
   stop)
    echo "Stopping test.js"
    # kill application you want to stop
    killall -9 node
    # Not a great approach for running
    # multiple node instances
    ;;
  *)
    echo "Usage: /etc/init.d/test {start|stop}"
    exit 1
    ;;
esac

exit 0

If you'd like to do sudo node, you can add the PATH to Defaults secure_path using sudo visudo.

Also, I would recommend using something like forever to keep your process running after crashes and what not.

Kevin Reilly
  • 6,096
  • 2
  • 25
  • 18
  • I tried to add the full path to the binary as suggested and I'm seeing the same result. I can start it manually, but it will not start on boot. After making the changes I ran `chmod +x /etc/init.d/MyApp` and removed and re-added to rc.d. My plan is to move to using forever after I can get it to trigger on boot. – user2650875 Feb 04 '14 at 12:47
  • When you try to start it manually, you are doing sudo /etc/init.d/MyApp start? This is how I determined I was having a PATH issue. – Kevin Reilly Feb 04 '14 at 16:38
  • Correct. I am calling `sudo /etc/init.d/MyApp start`. – user2650875 Feb 04 '14 at 17:02
  • Hmm... that is strange. You can execute the node application as root also? Is it an application that stays running, such as a web server? Did you try piping the output to a log like in my example with `> test.log` and checking the log? I wasn't able to find a log of the issue starting in any file of `/var/log`, but perhaps I missed it. I'm not sure if `Provides: MyApp.js` might be the issue, but you may want to try `Provides: MyApp` instead. – Kevin Reilly Feb 04 '14 at 22:15
  • Yes I can execute the node app as root or not as root. I am creating a log like in the example that you provided. The script does have a web server which continues to run continuously. Even triggering the boot script it will run without an issue. – user2650875 Feb 05 '14 at 01:43
  • Tried both ways `Provides: MyApp.js` and `Provides: MyApp`. No change in behavior. – user2650875 Feb 05 '14 at 01:51
  • Darn. I'm out of ideas. Except maybe trying a super simple app, such as a small web server example. I've got an example for my test that is verified working if you'd like to try it. Perhaps there is an error starting the app only when done via init.d – Kevin Reilly Feb 05 '14 at 02:00
  • I am too. I tried this example `#!/bin/bash NODE=/opt/node/bin/node SERVER_JS_FILE=/home/pi/app/server.js USER=pi OUT=/home/pi/nodejs.log case "$1" in start) echo "starting node: $NODE $SERVER_JS_FILE" sudo -u $USER $NODE $SERVER_JS_FILE > $OUT 2>$OUT & ;; stop) killall $NODE ;; *) echo "usage: $0 (start|stop)" esac exit 0` It gives me the same result. Executes manually but not automatically. It will run with a simple web server that returns "Hello World", but not my full app. – user2650875 Feb 05 '14 at 02:57
  • Got it! There was a path error in my app that was causing it error when running from init.d. The log was being overwrote be something else so I couldn't catch well enough. Thanks for all the help! – user2650875 Feb 05 '14 at 03:12
  • Awesome! So glad you got it figured out. My pleasure. What was the specific issue? Just for my own future reference. Needed to use __dirname or ./../ style or wha? – Kevin Reilly Feb 05 '14 at 07:15
  • 1
    Oh, and I just realized that >> is better than > in this case because it will append to the log instead of starting a new one. That may explain the overwrite scenario you were talking about. – Kevin Reilly Feb 05 '14 at 07:19
  • My app was trying to load "config.json" originally. I changed this to `./app/MyApp/config.json` because it wouldn't run when calling it manually to begin with. I ended up having to use the full path to get it to execute from booth `/home/pi/app/MyApp/config.json`. – user2650875 Feb 05 '14 at 12:39