/node-red-heroku

Node-RED to run on Heroku

Primary LanguageJavaScript

Node-RED for Heroku

Here are some hints on how to get Node-RED running on Heroku. I am not sure all instructions are complete, or in the correct order, because I have done it all over some time, but I will try to get in the most tricky stuff.

Running Node-RED on Heroku is an alternative to running it on your own hardware. There are advantages and drawbacks with both alternatives.

Introduction

I am using a simple Node-RED process that is reading data from MQTT, sending some data back to MQTT and some data further to ThingSpeak.com. I will use Heroku only for running the Node-RED process, not for changing it, so I will run Node-RED without GUI, and with all the flow config uploaded from files. To create and change the flow, I use a local instance, and then deploy it to Heroku.

All you need

  • git
  • Node.js
  • An account on Heroku, and the Heroku toolbelt installed. This is very well documented at Heroku. Use the Node.js instructions.

In this example I have also used:

  • An MQTT queue, for example at cloudmqtt.com.
  • A channel at ThingSpeak.com (Not necessary for the main issue here)
  • Something generating data to the MQTT

Preparations

Make sure you have all you need (see above). Then

  • Install Node-RED
  • Configure Node-RED and get it working locally
  • Set up .gitignore
  • Set up Heroku
  • Deploy to Heroku

The Node-RED installation guide explains installing Node-RED locally perfectly, so I will not repeat that.

Configure Node-RED

Create a separate directory for the app, where you put everything here. Create a .node-red sub-directory. Copy the original settings.js file here. You need the settings.js file to configure Node-RED. Take a special look at the adminAuth setting. This is necessary if you are going to use the node editor. Read about Security in the Node-RED doc.

Use the disableEditor: false setting to enable (false) or disable (true) the editor.

You can run Node-RED locally to create flows, using this command:

node-red --settings ./.node-red/settings.js --userDir ./.node-red 

After installing Heroku, you can start a local app using the command heroku local web.

When you create flows, it will be stored in a flows.json file .node-red directory. Credentials will be stored in a flows_cred.json file.

Keep your credentials secret

To keep the credentials safe, move them out of the flows_cred.json file and in to environment variables. Examples:

MQTT_USER=<MQTT username>
MQTT_PASSWORD=<MQTT password>
THINGSPEAK_API_KEY=<ThingSpeak API key>

You may create a shell script file to set them locally, and another one to set them on Heroku.

For example, to set up local variables, create the script local_config_var_setup.sh:

export MQTT_USER=secret
export MQTT_PASSWORD=anothersecret
export THINGSPEAK_API_KEY=secretsecret

Run this script like this: . local_config_var_setup.sh The preceeding dot is important.

To set up variables on Heroku, create the script heroku_config_var_setup.sh:

heroku config:set MQTT_USER=secret
heroku config:set MQTT_PASSWORD=anothersecret
heroku config:set THINGSPEAK_API_KEY=anothersecret

Run this script after you have configured Heroku (see below), like this: heroku_config_var_setup.sh.

After creating scripts with your environment variables, move the content in the flows_cred.json file into another script name postinstall.sh. Example:

# Create the flows_cred.json file with credentials from environment variables

FLOWS_CRED_FILE=.node-red/flows_cred.json
cat > $FLOWS_CRED_FILE << EOF
{
    "1183f03b.fae04": {
        "user": "${MQTT_USER}",
        "password": "${MQTT_PASSWORD}"
    },
    "d56617a5.79e518": {
        "apiKey": "${THINGSPEAK_API_KEY}"
    }
}
EOF

The code between the two EOFs is the content from your flows_cred.json file (in your local .node-red directory), but with the secrets replaced with environment variables.

Keeping the Heroku-app awake

There is one drawback with running Node-RED on Heroku. In order to work, Node-RED must be running all the time. That requires "dyno" time, so this app alone may tak up all your free dyno time. Of course, you can buy more time to get rid of the problem.

If you are using free dynos at Heroku, since Node-RED is running in the background, you will need some tool pingning it every 30 minutes to keep it awake. I am not sure if this is necessary if you use paied dynos. Anyway, a simple solution is to have Node-RED send an HTTP request to itself every 15 minutes. I found no way of starting a flow in a loop, so I wait for a "keepalive" message on MQTT, send the HTTP-request, wait 15 minutes, then send a new keepalive message to MQTT. It seems to work. Probably there are simpler ways to do this in Node-RED. Please let me know if you know about one.

Set up Heroku

You can follow the instructions on Heroku to create the Heroku app, but before you do that, make sure you update your .gitignore file to keep your seecrets out of git. Example:

*.backup
.sessions.json
flows_cred.json
heroku_config_var_setup.sh
local_config_var_setup.sh

The flows_cred.json file will be created dynamically by the postinstall.sh script. The shell-scripts are those that keep your secrets.

For other configurations, see the code to get examples of

  • app.json
  • package.json
  • Procfile
  • settings.js
  • postintall.sh

The Procfile is used to start the app on Heroku.