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…
-
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.
-
CREATE ELASTIC IP
In AWS create an elastic IP & associate it to your new Bitnami Parse instance. -
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.
-
POINT DOMAIN TO ROUTE 53 NAME SERVERS
In your domain registrar dns settings point the domain to the Route 53 name servers. -
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.
-
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.
-
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.
-
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.
-
STOP THE PARSE SERVER & DASHBOARD
- Run the following commands in your SSH console:
sudo /opt/bitnami/ctlscript.sh stop
- Run the following commands in your SSH console:
-
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.
-
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
- Run the following commands in your SSH console:
-
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.
- Run the following commands in your SSH console:
-
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*
- Run the following commands in your SSH console:
-
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
- Run the following commands in your SSH console:
-
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/bashsudo /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
-
MAKE SCRIPT FILE EXECUTABLE
Run the following commands in your SSH console:
sudo chmod +x /opt/bitnami/letsencrypt/scripts/renew-certificate.sh -
OPEN CRONTAB EDITOR
Run the following commands in your SSH console:
sudo crontab -e -
ADD TO CRONTAB
Run the following commands in your SSH console:
0 0 1 * * /opt/bitnami/letsencrypt/scripts/renew-certificate.sh 2> /dev/null -
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 -
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>
-
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
}
}
- Your config file should look something like this:
-
SETUP PARSE DASHBOARD CONFIG
Just make sure the serverURL value is “https://DOMAIN.COM” (your domain obviously) -
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 -
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 -
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.