Eternal applications with pm2 and resin.io

Last week one of our users Robin Remuer asked a question in our community forum. Robin wanted his node app to run continuously, automatically restarting the process if it hits unexpected errors. And I see why running remote devices daemon to monitor your processes on those devices is essential, unless you're the type of guy who loves spending his Saturday watching logs scroll across a screen.

Resin.io restarts your container when it boots, but doesn’t restart the container if an internal process fails. A dead device or process means patchy data so let's keep our devices alive, forever ever like Outkast!

forever

Robin suggested something like monit, but I wanted a super simple variation, my searches led me to npm. There are two popular node process managers out there forever & pm2. They are fairly similar, but pm2 integrates with keymetrics to give you a realtime dashboard so I chose pm2.

Assuming you have your device connected to your resin.io. (If you don’t take a look here.) Let’s clone our demo and push it to your device.

git clone https://github.com/resin-projects/resin-pm2-monitor.git  
git remote add resin [resin-app-remote-endpoint]  
git push resin master  

While that's pushing to your device lets take a look at the code. The Dockerfile just builds image with node pre-installed. It then installs pm2 globally via npm and runs start.sh when the container lands on the device.

start.sh, links our devices pm2 instance to the keymetrics API. It also tells the pm2 daemon to run server.js forever and spits out some logs.

pm2 link $PUBLIC_KEY $SECRET_KEY $RESIN_DEVICE_UUID  
pm2 start /app/server.js  
pm2 logs  

Server.js runs a simple http server. To illustrate that pm2 will keep our processes running irrespective of errors, I’ve set a timeout that throws an error after 5 seconds.

/* break the server after 5s */
setTimeout(function () {  
  util.puts('Throwing error now.');
  throw new Error('User generated fault.');
}, 5000);

Now create a keymetrics account, create a bucket and copy your private and public keys.

On your resin.io dashboard add your keymetrics public & private key as enviroment variables that we reference in our start.sh script.

Imgur

Now have a look at your logs on your resin.io dashboard.
Imgur

It will run through a loop of throwing our “user generated error” and restarting the server.js process. This process will continue forever unless the time between errors is less than 1 second.

If you visit your-device-IP:8080 you’ll see the eternal server running.

This server will never die! MWAHAHAHA!

You should also see your device in your keymetrics dashboard. It will be named by the device ID that resin.io initially assigns on first boot.

Imgur

KeyMetrics gives you live readings of your CPU and memory usage which could be useful for debugging in some situations. Also it will notify me when it loses connection with my device, meaning I get an email if my device drops offline.

It has a host of custom configurations you can make too. Creating custom events, alerts and actions. However its’ free tier only allows one device, so until I have a really good use-case I won’t be running more than one device on the service.

Imgur

Either way its great hack to keep a close eye on your remote devices health and keep processes running 4evs! Thanks for the great question Robin!

Is there a process management tool better suited for IoT applications? Leave us a comment and we'll take a look!

Have questions, or just want to say hi? Find us on our community chat.

comments powered by Disqus
Terms of Service | Privacy Statement | Master agreement | Copyright 2019 Balena | All Rights Reserved