Reverse Proxy with Node Red

Node-Red SSL

To use Node-Red out in the free world it needs a chaperone, that happens to be reverse proxy at the moment. If you are starting off from the beginning I would probably recommend following this guide. That’s assuming you have an Ubuntu server and are running Node-Red from there and you don’t mind running Nginx. What if you already have a server that may or may not be Ubuntu. Maybe you don’t like Nginx or maybe you already have Apache2 running. Or what if you are running Node-Red on a Raspberry Pi? Then that guide doesn’t work necessarily.

I searched all over again (briefly) on setting up Node-Red with SSL and or reverse proxy and it seems everyone has done it but no one is willing to share steps to do it? Is it that easy that it doesn’t need to be said? I wish I had found a write up to point the way, as it is simple but not necessarily easy. Especially for the average or new RPi tinkerer.

This is how I got it working. There may be other ways, and better ways but this is what I found worked for me. YMMV.



  • A TLD domain pointed at your server.
  • A server connected to your network running Apache2 (could be a Pi!)
  • Your server open to the world (port forwarding required)
  • Legit non-self-signed SSL certs. Let’s Encrypt is free.
  • mod_proxy installed and enabled on the Apache server, here’s a good guide (only step #1 is needed)
  • Node-Red, either on the same server or another (like a RPi) doesn’t matter (same network)
  • Don’t forget to enable Node-Red admin password protection too.


I am going to assume that you already own the domain and have it setup and working so that you can go to and it pops up. HTTPS, with a green padlock. If not, you need to buy the domain and point the DNS to your servers IP and create SSL certs, port forward yada yada. I host a server at home, makes it easy. For example, example and example. Oh and here are some Let’s Encrypt examples for Nginx and Let’s Encrypt on Apache.

You will need to edit your sites-available conf files and add the stuff for reverse proxy. You need more than just Node-Reds base URL to have a reverse proxy. I found it was best/easiest (shit maybe its required I don’t know, I’m just dangerous) to add a line for each webpage I was going to use specifically. So far thats Twilio voice, sms and Amazon Alexa.


Here is my Ubuntu Apache2 site-available conf for reverse proxy:


I’ve got a reverse proxy for each call I am going to make within Node-Red when using Twilio. These need to be accessible from the free world (to Twilio or Amazon etc). If you need more pages available to the world toss em in.

For example is what would be available to the world now.

Restart apache and you should be good to go.


Securing Node-Red

Node-Red-Admin (to hash a password)

Adding SSL to Node-Red

Let’s Encrypt SSL Certificates

Node-Red IVR with Twilio


A while back I posted about using Twilio and Node-Red to send/receive SMS messages. I was fiddling around with some older project stuff (uncompleted) earlier today and bounced into the IVR setup I had. Wondering if it was working I called it, and no it wasn’t. So I had to fix it. It took me a minute to come across all the related pages needed to get it working again so I decided to compile them here.

What is an IVR?

Well if you Google IVR you get: Interactive voice response (IVR) is a technology that allows a computer to interact with humans through the use of voice and DTMF tones input via keypad.

And that basically sums it up. It allows you the person, to call a computer and have the computer know what you want when pressing 1, or 5. Similar to a phone switching system but they are usually used to report some kind of information instead of route calls. IVRs basically cut out someones job once upon a time.

A better example is of a field technician calling an IVR system to read back what signals were received on the clients security system he just tested.

What we are doing here?

Were are going to get a basic IVR running on our Node-Red server to interact with and read back data or to activate/deactivate things over MQTT. If you would rather (and/or) use SMS to achieve kinda the same thing read here.



The Flow!

the flow

Here is the glorious flow!

You will need to create a global and have its value set so the IVR can read it back (in this example).

Drop a line in the comments if you have a question.


What helped:
old outdated flow

[{"id":"4868a284.66517c","type":"http response","z":"feaafa48.a34f88","name":"Send TwiML","x":870,"y":200,"wires":[]},{"id":"1444c0f8.9e1bff","type":"http in","z":"feaafa48.a34f88","name":"Incomming Twilio Call","url":"/twiliovoice","method":"post","upload":false,"swaggerDoc":"","x":316,"y":202,"wires":[["8cebf57a.769bc8","a77ee63.fbb7618"]]},{"id":"8cebf57a.769bc8","type":"function","z":"feaafa48.a34f88","name":"Process Call","func":"var twiml_response = \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\" standalone=\\\"yes\\\"?> \\\n <Response> \\\n <Gather action=\\\"\\\" numDigits=\\\"1\\\"> \\\n <Say voice=\\\"woman\\\">Welcome to Node-Red. For power usage press 1. To ring the bell press 2. For anything else press 3</Say> \\\n </Gather> \\\n <Say voice=\\\"woman\\\">Sorry, I didn't get your response.</Say> \\\n </Response>\";\nmsg.payload = twiml_response;\nreturn msg;","outputs":1,"noerr":0,"x":630,"y":200,"wires":[["4868a284.66517c","daf3c74e.9d90e8"]]},{"id":"2e446272.06064e","type":"http in","z":"feaafa48.a34f88","name":"IVR Data Call","url":"/twilioivr","method":"post","upload":false,"swaggerDoc":"","x":290,"y":280,"wires":[["f769d46d.3e7fc8","a306c4e8.68fd58"]]},{"id":"daf3c74e.9d90e8","type":"debug","z":"feaafa48.a34f88","name":"","active":true,"complete":false,"x":870,"y":280,"wires":[]},{"id":"f769d46d.3e7fc8","type":"debug","z":"feaafa48.a34f88","name":"","active":true,"complete":false,"x":630,"y":320,"wires":[]},{"id":"a77ee63.fbb7618","type":"debug","z":"feaafa48.a34f88","name":"","active":false,"console":false,"complete":"payload","x":630,"y":160,"wires":[]},{"id":"a306c4e8.68fd58","type":"function","z":"feaafa48.a34f88","name":"handleGather","func":"// Use 2 outputs, 2nd is for mqtt topic/payload combination\n// Could be useful to post other caller info to a topic\nvar mqttOut = null;\nvar responseMsg = \"\";\n\nvar name = \"wholehouse\";\nvar reading =[name];\nvar digit = msg.payload.Digits;\nif( digit == \"1\" ) {\n var twiml_response = \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\" standalone=\\\"yes\\\"?> \\\n <Response> \\\n <Say voice=\\\"woman\\\">Power usage is \" + reading + \"</Say> \\\n </Response>\";\n msg.payload = twiml_response;\n} else if( digit == \"2\" ) {\n\tmqttOut = {topic: \"bellduino/ring\", payload: \"ringmybell\" };\n var twiml_response = \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\" standalone=\\\"yes\\\"?> \\\n <Response> \\\n <Say voice=\\\"woman\\\">Turing on the bell</Say> \\\n </Response>\";\n msg.payload = twiml_response;\n} else {\n\tresponseMsg = \"You pressed \" + digit;\n}\n\nreturn [msg, mqttOut];","outputs":"2","noerr":0,"x":640,"y":280,"wires":[["4868a284.66517c","daf3c74e.9d90e8"],["a023a81c.a3e318","442a4b04.0c3c64"]]},{"id":"413a0cf4.24b0e4","type":"globalGetSet","z":"feaafa48.a34f88","name":"Text Global","topic":"","context":"msg","variable":"payload","outContext":"global","outVar":"wholehouse","x":490,"y":380,"wires":[[]]},{"id":"390ea068.1c8f8","type":"inject","z":"feaafa48.a34f88","name":"","topic":"","payload":"42.1","payloadType":"num","repeat":"","crontab":"","once":true,"x":290,"y":380,"wires":[["413a0cf4.24b0e4"]]},{"id":"a023a81c.a3e318","type":"mqtt out","z":"feaafa48.a34f88","name":"","topic":"","qos":"","retain":"","broker":"bdbaaa3f.072c48","x":850,"y":400,"wires":[]},{"id":"442a4b04.0c3c64","type":"debug","z":"feaafa48.a34f88","name":"","active":true,"console":"false","complete":"true","x":850,"y":360,"wires":[]},{"id":"bdbaaa3f.072c48","type":"mqtt-broker","z":"","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"willTopic":"","willQos":"0","willPayload":"","birthTopic":"","birthQos":"0","birthPayload":""}]

view raw
node-red twilio IVR
hosted with ❤ by GitHub



The ATOM editor

ATOM Editor

When I ran with the unwashed (ms windows) I used notepad++, then I moved to sublime when I started using a mac. I had used it for several years, then I decided to look for alternatives one day. I can’t remember why I was unhappy with sublime. I tried Brackets, Komodo, Aptana Studio and a few others but they didn’t feel right. Then I found ATOM, and that felt right. Maybe because it was so similar to sublime, that’s probably it. But it is so much more. It has many plugins you can well, plugin. You can make it just like sublime (but its better), and that may help with the transition. Fuck notepad++ that shit is old news and windows only, and windows fucking sucks. ATOM is cross-platform. Even if I had to do it all over again I would choose mac or Linux over windows, except for gaming (I bought a PS4, yeah fuck xboxes too). That is the only thing you can do with windows that makes sense, but then it doesn’t even really make sense. Everything about windows is wrong but that’s for another story all together.


READ THIS or at least skim through it

One of the most helpful plugins I have found is atom-beautify which is the reason I decided to write this post. Because it was such a pain in the ass to get this running. But in the end it wasn’t. It was a ID10T issue. I didn’t understand what exactly it was supposed to do, exactly. But now I do and knowing is half the battle! What is a beautifier? Well it takes all that horribly formatted code and makes it all nice and pretty to work with and look at. Its so fucking helpful.

I had installed atom-beautify and its sub component php-cs-fixer. Upon opening a php file I received an error that php-cs-fixer could not be found. So it looks like I need to install it. Well the ATOM websites directions for installing php-cs-fixer on a mac are wrong. You need to visit FriendsOfPHP at Github. Those directions there do work.

I did a few things to try to get it to work, these are probably not the correct steps, but they got me there. In the end I am thinking one may be able to use the compose install and run with that, omitting the manual/curl install. Remember, I am on a mac (latest OS as of this writing).

I tried the composer install first.

But when I tried which php-cs-fixer I got nothing. Now I know I was using the wrong paths in hind-sight. If I were you I would try installing via composer then using the proper composer path in the settings. If that doesn’t work and you still get the error then you know you need to do the manual install as well. But I am thinking not.

Then I tried the homebrew, at first it was producing errors for read/write permissions on a folder. Persistence paid off and it eventually just installed without any errors. Go figure. But alas, doing which php-cs-fixer  produced nothing once again. So I tried the manual installation, as the others did not produce any positive results. From a terminal do this:


Turns out this comment also explains the same thing on how to install it.

Then, just run which php-cs-fixer, and it should hopefully give you good news (a path). I copied that path, and pasted it in the config settings for atom-beautify and php-cs-fixer. But that also produced the same errors from atom-beautify/php-cs-fixer. Then I found this In that picture lied my salvation. I was using the wrong path this whole time and didn’t know it. As soon as I changed the path for php-cs-fixer I was good to go. That path was:


Also of note, no matter what I did I was not able to get php php-cs-fixer  to work, never. I saw it posted all over but it never worked for me. So I did get it working, but I still thought it wasn’t working. Because it wasn’t doing anything (or so I thought). I was running the beautifier on all kinds of pages and I didn’t see any code change, I would even remove all indents and nothing! What the fuck dude? So I tried some html pages, and some JavaScript files. Those all worked just fine. It was just the php pages that were not working. Well as it turns out it was working just not how I though it should, which it should. All of the files I have that are php are intermixed php with html, for websites. I rarely have pages that are pure php. Well this plugin doesn’t structure html, at all. Or even call to the html formatter, as I think it should. It just formats pure php. So if you change the page type to html and run the beautifier it works just fine. I was expecting it to restructure all the contents of the php file, not just the actual php code. My mistake.

TLDR; php-cs-fixer just formats/indents pure php code, not php code intermixed with another language like html.. Also you need to update php5.6 to 7+ and I would install php-cs-fixer via composer, check your paths.

View Post

I am not responsible for anything that you fuck up or that goes wrong. Take these steps at your own risk. You have been warned.

Creating a mini NES with a Raspberry Pi

Mini NES RetroPie
Mini NES RetroPie
Mini NES RetroPie

It all started with the Nintendo Classic craze. I had a friend that was rambling about one the other day. I mentioned that I could totally make him one but better because it would emulate more than just Nintendo. Enter RetroPie. I was looking at putting the bill of materials together and thinking of cases for the mini NES, then I realized why not just print one! So BAM and BAM. 
then this 

Then this for giggles


Here’s what we are doing

  1. Flashing RetroPie to an SD card for a Raspberry Pi
  2. Soldering header pins to the RUN pin holes on the RPi
  3. Soldering wires to some push buttons
  4. Soldering some wires to an LED
  5. 3D Printing a mini NES case for the RPi
  6. 3D Printing a bracket for the NES case
  7. Glueing push buttons, LED and bracket into the printed case
  8. Wiring the LED and buttons to the RPi
  9. Testing it all


Here’s what you need

  1. Raspberry Pi (save yourself a headache, get a RPi 3!)
  2. RPi power supply MINIMUM of 2.5A!
  3. SD card 8gb+ class 10
  4. HDMI cable
  5. USB keyboard
  6. Network cable (even though the RPi 3 has wifi you will at least need to do the initial wifi setup with a LAN connection)
  7. A 3D Printer to print the case and the bracket
  8. (2) push buttons
  9. (2) male header pins
  10. Super glue and hot glue
  11. (1) red LED
  12. (1) 100 ohm resistor
  13. (6) pieces of jumper wire with connections (you can cut some in half if long enough)


Whats Up

I will assume you have a network connection (non wifi) a USB keyboard a TV or Monitor or tv with an HDMI connection and that you have active internet. You will need to know how to solder, and be somewhat comfortable with a terminal and hopefully the Linux environment. I also assume you have and know how to use a 3D printer. I will also assume that you know and are comfortable with Raspberry Pies. Lots of ASSumptions.

This post is not designed as a how to install RetroPie but more of a how to get RetroPie installed and create the scripts for shutdown the Pi and lighting the LED, then you can follow the first install guide by RetroPie to get you going with the actual RetroPie software.

View Post

I am not responsible for any damage that may happen to you, your computer, or your Raspberry Pi etc. Take this adventure at your own risk.