Bitnami Parse API SSL HTTPS / WSS With Apache Under Load Balancer Setup Guide

BITNAMI PARSE AMI SSL HTTPS & WSS SETUP WITH ROUTE 53 & LOAD BALANCER

Here’s a quick and dirty “how to” on setting up the Bitnami Parse AMI for SSL HTTPS & websockets WSS using Route 53, with elastic IP and load balancing.

If you got far enough to find this guide I’m assuming you’re at least a little familiar with the AWS side and at least a little familiar with Node.js.

I’m just giving a quick highlight on setting up the Amazon AWS side and focusing more on the actual Apache and Parse configuration. If you need a more in-depth guide on how to create/setup elastic IP’s, load balancer, using the AWS SSL certificate manager or Route 53 refer to Amazon’s docs or do a quick Google search for this.

You will need an SSH client like Putty & I recommend WinSCP or something like it to make editing Apache files and the config files a little easier than doing it through the console if you’re not super familiar with something like nano.

My hope is that this guide will help more developers coming from something like a LAMP stack or a Wordpress dev background get a basic Parse server and live queries running in AWS so you can spend more time developing and writing code and less time beating your head against the wall trying to figure out server-side Apache stuff and SSL under a bastardized configuration like we have here within AWS load balancing.

I’ve probably hit every brick wall there is to hit on setting this up twice now in the last 2 years so if you run into issues shoot me a reply here and I’ll try to keep an eye on this thread and help if I can.

The frustrating thing here can be that the few docs out there are for a basic Parse setup using something like Docker OR they’re for back4app which is it’s own thing. The other frustrating aspect is the little documentation out there for getting websockets working right under secure wss:// is geared towards Nginx and not Apache which the Bitnami AMI uses. Nginx may very well be the better solution for running websockets but for someone new to the stack the Bitnami AMI is the easiest way to get something setup to start playing with it and get something built quickly.

Separating your LiveQuery server and using an external Redis cache is a must for anything production here but again, this is geared towards those that are new to this stack and maybe even new to AWS and just want to get something up and running quickly to start learning it and see if Parse will work for what you need to build. This is why the guide is for setting up the LiveQuery server on the same instance and NOT going into separating it or the MongoDB or going into Redis caching at all.

Bitnami saves us TONS of time with these AMI’s & Parse is one of the few API BaaS platforms you can self-host with websocket/Live Query capability. If you’re a developer you know full well things happen and you can’t catch everything perfectly every time. I mention this because if you follow this guide and it breaks somewhere along the way instead of going insane for days or weeks trying to figure it out you should probably reach out to them, run their diagnostic tool, check your Apache log, check your Parse log and send them all of the info you can. If the Bitnami team is stuck reach out here in the Parse community.

Anyway, with all of that said hopefully this helps some of you…

  1. INSTALL THE BITNAMI AMI
    Install the Bitnami Parse AMI image

    • Create a private key if you don’t already have one, download it and keep track of where you put it.
  2. CREATE ELASTIC IP
    In AWS create an elastic IP & associate it to your new Bitnami Parse instance.

  3. CREATE ROUTE 53 HOSTED ZONE
    Create a new hosted zone in Route 53 for your domain.

    • For now just create an A record and point it to your elastic IP.
  4. POINT DOMAIN TO ROUTE 53 NAME SERVERS
    In your domain registrar dns settings point the domain to the Route 53 name servers.

  5. CREATE TARGET GROUPS
    Under the Load Balancer section in AWS instances select “Target Groups” & create a new targe group.

    • Create a target group for non-ssl using port 80 and select your Bitnami Parse instance as the target.
    • Create another target group for ssl using port 443 and again select your Bitnami Parse instance as the target.
  6. CREATE LOAD BALANCER
    Create an “APPLICATION” load balancer. This must be created as application and NOT classic.

    • Select internet facing, not internal
    • Select dualstack for the IP type.
    • Setup listeners for port 80, 443 & 1337.
    • Create SSL certificates for the 443 & 1337 listeners.
  7. CONFIGURE & POINT ROUTE 53 RECORDS TO LOAD BALANCER
    Return to Route 53 & finish configuring your dns records.

    • Change your A records from IP to alias and point them to your new load balancer for your Bitnami Parse instance.
    • Finish setting up any other dns records in route 53 now as you would normally.
  8. LOG INTO INSTANCE IN SSH CONSOLE
    SSH into your Bitnami Parse instance using the elastic IP you pointed at it.

    • Make sure you add the key you created and downloaded for the instance.
    • Username is bitnami.
    • Password is the password you set on your key you created and downloaded.
    • Once connected in SSH type sudo su to switch to root.
  9. STOP THE PARSE SERVER & DASHBOARD

    • Run the following commands in your SSH console:
      sudo /opt/bitnami/ctlscript.sh stop
  10. UPDATE SERVERADMIN AND SERVERNAME IN APACHE
    Replace default servername and serveradmin values in the Apache config files.

    • I’d recommend using something like WinSCP for editing files as I find it faster and easier personally. Otherwise you can do it through the console using nano.
    • /opt/bitnami/apache/conf/httpd.conf change the ServerAdmin to your email and ServerName to your domain name.
    • /opt/bitnami/apache/conf/vhosts/parse-vhost.conf change server name to your domain.
    • /opt/bitnami/apache/conf/vhosts/parse-https-vhost.conf change server name to your domain. // THERE WILL BE MORE TO DO IN THIS FILE LATER
    • /opt/bitnami/apache/conf/extra/httpd-ssl.conf change the ServerAdmin to your email and ServerName to your domain name.
  11. INSTALL LETSENCRYPT LEGO
    The bncert tool that comes preinstalled with the AMI will not work under a load balancer & elastic IP so we need to use this alternative method to generate our SSL certs

    • Run the following commands in your SSH console:
      cd /tmp
      curl -Ls https://api.github.com/repos/xenolf/lego/releases/latest | grep browser_download_url | grep linux_amd64 | cut -d ‘"’ -f 4 | wget -i -
      tar xf lego_v4.10.2_linux_amd64.tar.gz
      sudo mkdir -p /opt/bitnami/letsencrypt
      sudo mv lego /opt/bitnami/letsencrypt/lego
  12. GENERATE SSL CERTIFICATES
    *! MAKE SURE YOU CHANGE EVERYTHING THAT SAYS “[email protected]” TO YOUR EMAIL & “DOMAIN.COM” TO YOUR DOMAIN! *

    • Run the following commands in your SSH console:
      sudo /opt/bitnami/letsencrypt/lego --tls --email="[email protected]" --domains=“DOMAIN.COM” --domains=“www.DOMAIN.COM” --path="/opt/bitnami/letsencrypt" --tls.port :8443 run
      * I’ve experienced issues running the above command using TLS the first time prior to having any SSL certificates installed yet. If this fails you can run the following instead:
      (sudo /opt/bitnami/letsencrypt/lego --http --email="[email protected]" --domains=“DOMAIN.COM” --domains=“www.DOMAIN.COM” --path="/opt/bitnami/letsencrypt" run)
    • You should get a message returned in the console saying that the certificates were generated.
  13. MOVE CERTS TO APACHE BITNAMI FOLDER

    • Run the following commands in your SSH console:
      sudo mv /opt/bitnami/apache/conf/bitnami/certs/server.crt /opt/bitnami/apache/conf/bitnami/certs/server.crt.old
      sudo mv /opt/bitnami/apache/conf/bitnami/certs/server.key /opt/bitnami/apache/conf/bitnami/certs/server.key.old
      sudo ln -sf /opt/bitnami/letsencrypt/certificates/akashichealthrecords.com.key /opt/bitnami/apache/conf/bitnami/certs/server.key
      sudo ln -sf /opt/bitnami/letsencrypt/certificates/akashichealthrecords.com.crt /opt/bitnami/apache/conf/bitnami/certs/server.crt
      sudo chown root:root /opt/bitnami/apache/conf/bitnami/certs/server*
      sudo chmod 600 /opt/bitnami/apache/conf/bitnami/certs/server*
  14. CREATE AUTO RENEW DIRECTORY & FILE

    • Run the following commands in your SSH console:
      sudo mkdir -p /opt/bitnami/letsencrypt/scripts
      sudo nano /opt/bitnami/letsencrypt/scripts/renew-certificate.sh
  15. ADD COMMANDS TO AUTO RENEW FILE
    *! MAKE SURE YOU CHANGE EVERYTHING THAT SAYS “[email protected]” TO YOUR EMAIL & “DOMAIN.COM” TO YOUR DOMAIN! *
    Add the following to the renew-certificate.sh file you just created
    #!/bin/bash

    sudo /opt/bitnami/ctlscript.sh stop apache
    sudo /opt/bitnami/letsencrypt/lego --tls --email="[email protected]" --domains="DOMAIN.COM" --domains="www.DOMAIN.COM" --path="/opt/bitnami/letsencrypt" renew --days 90
    sudo /opt/bitnami/ctlscript.sh start apache
    
    • Hit CTRL-X, select save and exit & hit enter
  16. MAKE SCRIPT FILE EXECUTABLE
    Run the following commands in your SSH console:
    sudo chmod +x /opt/bitnami/letsencrypt/scripts/renew-certificate.sh

  17. OPEN CRONTAB EDITOR
    Run the following commands in your SSH console:
    sudo crontab -e

  18. ADD TO CRONTAB
    Run the following commands in your SSH console:
    0 0 1 * * /opt/bitnami/letsencrypt/scripts/renew-certificate.sh 2> /dev/null

  19. ENABLE REQUIRED APACHE MODULES
    Make sure the following modules are uncommented (no # in front of them):
    mod_proxy.so // I THINK THIS IS UNCOMMENTED BY DEFAULT
    mod_proxy_wstunnel.so // THIS IS NOT UNCOMMENTED BY DEFAULT

  20. ADD REWRITE RULE & REVERSE PROXY FOR WEBSOCKETS
    /opt/bitnami/apache/conf/vhosts/parse-https-vhost.conf should look like this:
    *! MAKE SURE YOU CHANGED “DOMAIN.COM” TO YOUR DOMAIN! *
    <VirtualHost 127.0.0.1:443 default:443>
    ServerName DOMAIN.COM
    ServerAlias *

      SSLProxyEngine on
      RewriteEngine On
      RewriteCond %{HTTP:Upgrade} websocket [NC]
      RewriteRule /(.*) ws://localhost:1337/$1 [P,L]
    
      SSLEngine on
      SSLCertificateFile "/opt/bitnami/apache/conf/bitnami/certs/server.crt"
      SSLCertificateKeyFile "/opt/bitnami/apache/conf/bitnami/certs/server.key"
    
      ProxyPass /parse http://127.0.0.1:1337/parse
      ProxyPassReverse /parse http://127.0.0.1:1337/parse
      ProxyPass / http://127.0.0.1:4040/
      ProxyPassReverse / http://127.0.0.1:4040/
    
      ProxyPass "/parse" "ws://127.0.0.1:1337/parse"
      ProxyPassReverse "/parse" "ws://127.0.0.1:1337/parse"
    </VirtualHost>
    
  21. SETUP PARSE SERVER CONFIG
    Open /opt/bitnami/parse/config.json in WinSCP or using nano in your SSH console.

    • Your config file should look something like this:
      {
      “appId”: “myappID”,
      “masterKey”: “MYMASTERKEY”,
      “appName”: “parse-server”,
      “mountPath”: “/parse”,
      “port”: “1337”,
      “host”: “127.0.0.1”,
      “serverURL”: “https://MYDOMAIN.COM/parse”,
      “databaseURI”: “mongodb://bn_parse:[email protected]:27017/bitnami_parse”,
      “liveQuery”: {
      “classNames”: [
      “_User”,
      “MYCLASS”, // YOU CAN ADD THESE LATER FOR EACH CLASS YOU WANT THE LIVE QUERY SERVER TO LISTEN TO
      “MYCLASS2”
      ]
      },
      “startLiveQueryServer”: “true”, // THIS STARTS THE LIVEQUERY SERVER
      “liveQueryServerOptions”: {
      “appId”: “myappID”,
      “serverURL”: “wss://MYDOMAIN.COM/parse/”,
      “masterKey”: “MYMASTERKEY”,
      logLevel": “VERBOSE” // THIS SHOULD ONLY BE SET IF DEBUGGING, REMOVE THE PREFIX "” TO ENABLE
      }
      }
  22. SETUP PARSE DASHBOARD CONFIG
    Just make sure the serverURL value is “https://DOMAIN.COM” (your domain obviously)

  23. RESTART APACHE & START THE PARSE SERVER & DASHBOARD BACK UP
    Run the following commands in your SSH console:
    sudo /opt/bitnami/ctlscript.sh restart apache
    sudo /opt/bitnami/ctlscript.sh start

  24. LET’S MAKE SURE THE PARSE SERVER & LIVEQUERY SERVER IS RUNNING UNDER SSL
    Open /opt/bitnami/parse/logs/parse.log. At the bottom you should see something like the following:
    [8409] parse-server running on https://DOMAIN.COM/parse
    info: Parse LiveQuery Server started running

  25. GO BUILD STUFF
    Assuming all went to plan, you now have a functional Parse server with the LiveQuery server running with SSL setup both on the AWS load balancer side as well as internally in Apache.

    On your client you should be able to add something like the following to connect to your new Parse server & the LiveQuery server:
    // INITIALIZE PARSE
    Parse.initialize(myappId);
    Parse.serverURL = https://DOMAIN.COM;
    Parse.liveQueryServerURL = wss://DOMAIN.COM;

    Look in the browser console in your client and see if you get a websocket error. If not you’re in business.

    You can now go build some stuff and use the super awesome live query listeners to update everything in real time for everyone.

    Now the next step is to setup a separate Redis Elasticache, separate the LiveQuery server to a separate instance & separate the MongoDB to a separate instance for speed and scalability. But that’s a whole other topic.

1 Like

FYI I shot this over to the Bitnami team so hopefully they’ll add a version of this to their own docs which right now are a little sparse to say the least on live queries and SSL within an AWS environment.

1 Like

What is the benefit of using Bitnami? Isn’t that the same parse server?

It’s just a quick easy way to spin up a full parse server in AWS.

1 Like

Cool thanks for writing this up, if the Bitnami team doesn’t document this officially, maybe we should.

1 Like

No problem, feel free to use it in your own docs if you want.

I think some of this could be carried over to a non-bitnami install as well under an AWS apache setup with a load balancer. Using LetsEncrypt LEGO to generate the certs internally, the rewrite/reverse proxy & using the AWS Cert Manager on the domain should work regardless of how you install Parse.

That said, from everything I understand from what I’ve read if you’re going to install parse yourself and plan to use live queries an NGINX server would be the better play as apparently NGINX handles websockets more efficiently.

I’ll probably do another for setting up a separate live query server with an AWS elasticache redis cluster once I get my own setup and working.

Another thing I discovered using the Bitnami build in AWS you’ll want to add the following to your config.json file if you want to use cloud code:

“directAccess”: “true”,