So I decided to move my site from the wonderful Firebase to AppEngine. This way I can code my own backend and do all sort of stuff.
Unfortunately, there is no automatic way to enable HTTPS for custom domains on AppEngine, thus I went through the journey of getting a certificate and uploading it to Google Cloud. Due to my inexperience in doing this manually, it has been quite the journey. It took me several days of trials and errors to nail the process, therefore I decided I would share with you my experience so that, hopefully, you don't have to go through the whole thing yourself.
In retrospect, it is pretty straightforward to make it work. Here are the steps:
Since I am getting a free certificate from LetsEncrypt, it should be noted that it only lasts for 90 days. You'll need to either repeat the procedure or find a way to automate it every three months or so.
Since some time, there is a new CA (Certificate Authority) around that issues trusted certificates for free. It is called LetsEncrypt: an awesome initiative with the goal of making HTTPS more accessible to everyone.
Getting a certificate from LetsEncrypt is simple and there are plenty of clients that allow you to do this. My suggestion is to use the certbot client (or any other client you can find). For a more in depth guide on how to proceed, you can follow through this wonderful article by Sam Thorogood.
If you are really lazy, you can take a leap of faith and let SSL For Free do all the hard work for you. The leap of faith being trusting the people behind that site to neither store nor exploit the keys you generate with it.
At some point, you will be asked by the client you picked (e.g - certbot) to verify that you own the domain. This step has been an utter nightmare for me.
If you go the regular route, you'll be asked to simply deploy a specific file to your server, so that you can prove that you own the domain you are requesting a certificate for. Unfortunately, this didn't seem to work for me, I went on a series of relentless attempts for two full days of painfully long AppEngine deploys. I finally gave up and tried the other approach, that I can't recommend enough.
Indeed, there's another way you can verify the domain by, which is to simply add a couple of TXT entries in your DNS configuration. It's easy and quickly done.
One step that I missed is combining the certificate you obtained, with the one provided by LetsEncrypt. Again, Sam describes this step in his guide, but I totally forgot to.
It's as easy as
cat your-cert lets-encrypt-cert > combined-cert.pem
Now to the easy part. Google's CLI comes in handy here, as we can simply run a command to let AppEngine know about our certificate:
gcloud beta app ssl-certificates create \ --display-name "my first cert" \ --certificate combined-cert.pem \ --private-key private.key
Here we are creating a name to be assigned to the certificate, sending the certificate itself, and our private key.
Boy did I mess up a lot. This one is another step I totally missed the first time! The previous gcloud command sneakily yields out an id between square brackets (e.g -
You need to use that ID to tell AppEngine to assign the certificate identified by that number, to our domain. Again this is one simple command:
gcloud beta app domain-mappings update YOUR_DOMAIN \ --certificate-id THAT_SNEAKY_ID
And that's it! If you didn't mess up as much as I did, you should now have a secure website. Congratulations!
Now, after all the work you've been through, you don't want some of your users to navigate to the plain-HTTP version of your site. Luckily, it's pretty easy to enforce HTTPS these days, and if your server is running in Node with ExpressJS, I've got the npm package for you.
It's called yes-https and will take care of everything. You'll just need to:
npm install --save yes-https
const yes = require('yes-https');
And there you go, another secure site just joined the Web!
Hope this helps anyone. Let me know if there’s anything unclear, or that you disagree with!