Node NodeJS with Lamp on Apache Bitnami Stack

I wanted to test some of the new Facebook Messenger bots and since “The Facebook” requests your services to have https, I wanted to leverage my existing domain that already has ssl setup.  Unfortunately when you pick a Lightsail instance, it’s Node.JS or LAMP.  Since I already had a LAMP instance, my goal was just to have Node running on top.

I was a little hesitant because I didn’t want to have Node conflict with Apache and take down my existing site.  What I learned is that NodeJS (or Node which are the same thing) won’t conflict as you can run your service on another port.  However, there is some setup that you need to take care of.  If you are nervous about messing up an existing instance, just spin up a new light sail instance which is similar to your existing and play around with the package installs on that one.

Install NodeJs

Assuming you already have a Lightsail Bitnami LAMP instance (or similar), you need to install two things:  NodeJS and NPM.  Basically NodeJS is the engine that will run your code and NPM is a package manager.  I was confused on how to get Node and NodeJS both installed not realizing they are the same thing.  The commands to do it are:


sudo apt-get install nodejs
sudo ln -s /usr/bin/nodejs /usr/sbin/node

The 2nd line is to create an alias so that node and nodejs do the same thing

Then install the packages that support the nodejs code


sudo apt-get install npm
npm install

Make sure you run the second line otherwise you downloaded all the packages, but didn’t actually install.

Test you have it working by typing `nodejs –v` and it should tell you the version you have running.

Do a hello world type test now and save these two lines in a script called helloWorld.js


var sys = require("sys");
sys.puts("Hello World");

Now type nodejs helloWorld.js and it should simply say Hello World

Apache Configuration

Next you need to modify your Apache configuration so it knows to pass requests for Node.  For this, you need to know what port your application will run on.  For my setup, I used port 8080.

Open up your /home/bitnami/stack/apache2/conf/bitnami/bitnami.conf file and add these lines to the section of your config that is for port 443


SSLProxyEngine on
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
ProxyRequests Off
ProxyPreserveHost On

<Location /webhook >
   ProxyPass http://localhost:8080/webhook Keepalive=On
   ProxyPassReverse http://localhost:8080/webhook
</Location>

The key is the Location section above.  This tells apache that for any request that starts with /webhook to pass the request to what you had configured as the url.

Restart Apache for these settings to be applied.  When it restarts, if you did something wrong, it will show you the error.

To be honest, I’m not sure if all those SSLProxy* config settings are necessary, but that’s how it is working in my environment.

Testing Running  A Server

You should have to make one more Lightsail config, but lets setup a test server to start.

Copy and pasta this into a new file and save it as server.js


var sys = require("sys"),
my_http = require("http");
my_http.createServer(function(request,response){
sys.puts("I got kicked");
response.writeHeader(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}).listen(8080);
sys.puts("Server Running on 8080");

Now start it by running nodejs server.js and it should say “Server Running on 8080”

From another terminal session, on the same server, telnet localhost 8080 and it should connect.  Now try doing it from somewhere externally by typing in the URL of your server and what you configured in the apache config.  For instance, https://www.yourdomain.com/webhook   Remember to use https and not to include the port number as that’s already setup in the config.  If that does not work, then you need to open up port 8080,  Go to your LIghtsail instance, click on Manage, Open a CUSTOM port 8080 and save.  Try it again and it should work.  Another way you can test, which will not be be https is to use http://www.yourdomain.com:8080/webhook  They should do the same thing, except not be encrypted.

Run Node as a Service

Once you ctrl-c out of your terminal session, your NodeJS service will stop.  To keep it running in the background install forever.


sudo npm install -g forever

To start it as a service, simply use this command:


forever -o output.log -e error.log start app.js

This will start the service in the background but also put the output into the log files so you can monitor the interactions. To see if it’s running, just run forever list

Facebook Configuration

The entire point of me doing this was to actually test a Facebook Messenger Bot.  I downloaded the sample code from https://github.com/fbsamples/messenger-platform-samples I had a few issues in getting it to work so here are some hints:

Obviously, update the app.js file to reflect the port you are running the service on.  Search for port 5000 which is what the sample code uses and replace it with port 8080.

Your page access token will sometimes change.  If you are getting this error message Failed calling Send API 400 undefined { message: ‘(#100) No matching user found’, then copy and paste it again in your config/default.json file

Your appSecret is from your developer page, click on the app you setup to test and click “Reveal App Secret”.

If Facebook is kicking back errors from your webhook, you can tail your access and error logs to see what they are sending.  You should see a request like this which you can use to manually debug: /webhook?hub.mode=subscribe&hub.challenge=123343443243243&hub.verify_token=your_test_token_that_you_created

My application would error on start due strict mode.  I had to comment out the line (still need to figure out why).

Also, if your proxy is still not working, try adding this line:  app.enable(‘trust proxy’);

Lastly you can start the code by typing npm start in the directory where app.js is located or do nodejs app.js  I initially didn’t understand the “npm start” command until I realized it simply starts whatever it find in current path.

Hopefully that helps.  Another great tutorial similar to the Facebook one can be found here:  https://github.com/jw84/messenger-bot-tutorial

Leave a Reply

Your email address will not be published.