Blog
Learning material for professionals eager to explore the science behind building a successful online product

Getting my site on HTTPS with AppEngine

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:

  1. Get a free certificate
  2. Upload it to Google Cloud
  3. Map it to the domain
  4. BONUS: Force HTTPS with yes-https

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.

Step 1: Get a free certificate

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.

Step 1.1: Verify that you own the domain

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.

Step 1.2: Combine your certificate with LetsEncrypt's one

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

Step 2: Upload it to Google Cloud

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.

Step 3: Map it to the domain

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 - [1234567]);

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!

BONUS ROUND: Force HTTPS

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:

  • Install the module with npm install --save yes-https
  • Require it as usual const yes = require('yes-https');
  • Plug it in as an Express middleware app.use(yes());

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!

Care to leave a comment? Drop down a line on the Twitters