Add SSL to your personal website

Give yourself a gift this holiday season, and add SSL to your personal site. The web is going secure, and it's time to be part of the solution. This article details how I turned on SSL + custom domains, plus automated deploys, for my personal site for the cost of a domain (which I already had) and $5/year. Read on!


Turns out, it's easier (and more affordable!) than you think to add SSL to your website. But first, why bother? There are lots of reasons why you should care about adding SSL:

  • Search engines are preferring SSL
  • New web APIs (like service worker) mandate SSL
  • Users trust SSL
  • Bonus: SSL can help enable HTTP/2 on some servers
Your setup will vary, so look for the easiest/shortest path to SSL for your particular site. Everyone has factors they want to optimize for. Here's what I was trying to optimize, as I looked for a solution.

I needed a solution that was:
  • Affordable
    • The solution should be very, very affordable. Affordable, in this context, means "as close to free as possible". My personal website is extremely low traffic. It doesn't make sense for me to pay a lot of money for something so small.
  • Easy
    • I don't have time to manage my personal site. The solution has to be simple and quick.
  • Sustainable
    • Because I don't have time to manage my site, I need a solution that is "set and forget" for as long as possible.
  • GitHub friendly
    • My site's source is on GitHub, and I needed a hosting+SSL solution that integrated with a "push to deploy" model.
  • Static file friendly
    • My personal site is extremely simple. I don't need anything other than a few static files.
  • Works with Custom Domains
    • I want to use my own domain.
I looked at a lot of options. Here's what didn't work for me, for a variety of reasons. They may work for you.

  • Managing my own VPS (e.g. on Digital Ocean or EC2).
    • This option completely rules out easy and sustainable. Manual configuration of servers, or keeping linux distros up to date, are two things I absolutely do not want to be doing.
  • Google Cloud Storage
    • GCS does serve static files, and even supports custom domains. However, they don't support custom domains and SSL. Bummer. It also doesn't support basic static file hosting feature like redirects, so it's probably not an option anyway.
  • GitHub Pages
    • Great integration with GitHub (of course :), but don't they don't support custom domains and SSL. They support custom domains, and SSL via the github.io domain, just not custom domains and SSL together at the same time.
  • Amazon Web Services
    • I'm not aware of an AWS product that meets my needs. Maybe they have some awesome static file server with custom domains and SSL and git integration? I didn't see one.
  • Firebase Static Hosting
    • This open is actually really good, and it was almost my solution. Their setup is very simple, they support custom domains and SSL, and they have decent GitHub integration (it requires just a little bit of scripting to deploy after a push). The only downside is that it costs $5/month for custom domains (but, the certificate is free and provided by Firebase). $60/year is a small price, especially considering the Firebase gives you an SSL certificate for free! Also, their static hosting is very good: they give you configuration options for redirects, custom 404 pages, and more. It's a very good option for most people. But, if $60/year is an issue (and it was hard for me to justify $60/year for a site that maybe serves 60 pages a year :), keep reading.
    • I should also note that it doesn't appear that Firebase supports IPv6 hosting. At least, their instructions didn't tell me to add IPv6 addresses to my DNS. This is probably a minor thing.
The hosting option that did work for me, after a lot of searching and reading, was: Google App Engine.

Google App Engine has a few things that made it a winner for me:
  • A completely free tier.
    • My personal site is way, way, way under the free tier limits.
  • Runs itself
    • App Engine just keeps on trucking, especially for a simple static site.
  • Custom domains
    • No need to upgrade to a paid tier to get this feature.
  • Custom certificates
    • You need to upload your own certification, but you don't need to upgrade to a paid tier to get this feature.
  • Fine for simple static sites
    • For just a few pages, App Engine's configuration is decent. It's not as simple as Firebase's, but I don't anticipate needing redirects.
  • Can be deployed from a push to GitHub
    • Travis to the rescue! The free Travis CI system can trigger a deploy to App Engine, when you push to GitHub.
  • Support for "naked domains"
    • App Engine can now serve http://example.com. For the longest time, they request a subdomain, but naked domains now work.
  • Supports IPv6
    • Because future.
Google App Engine isn't perfect. If you want to do any redirects, you need to start writing Python. And it's not obvious how to setup App Engine for pure static hosting, nor is App Engine the simplest way to serve a static site (e.g. it's not good at recognizing optional trailing slashes in URL paths), but it can be done.

The next question was: where do I get an inexpensive SSL certificate? I looked around, and there are a lot of options and resellers. I purchased a three-year personal cert from https://ssls.com for a total of $15. That's 1/4 the price of one year of hosting with Firebase. The fact that I found a very affordable SSL cert is what really made App Engine a winner for me.

I assume you know about GitHub, how to get an App Engine account, and how to connect Travis to automate the builds. I know this looks like a lot of steps, but, remember, I'm doing three things here: custom domains, SSL, and automated deploys.

Here's a list of docs and some manual steps that helped me get my personal website setup for custom domain, SSL, and automated deploys from GitHub:
  • Custom domains and SSL for App Engine
    • Helps you link your domain to App Engine and walks you through generating the necessary files for the certificate.
  • Affordable personal SSL certs from ssls.com
    • I purchased a "PositiveSSL" cert with a three-year expiration.
    • Generate a CSR by running openssl req -nodes -newkey rsa:2048 -keyout myserver.key -out server.csr in a temp directory
    • Upload the CSR to your certificate vendor
    • You may need to perform additional verification steps. For example, I had to verify that I owned by domain by uploading a file to a special location on my server that serves my domain name.
  • Generating a service account from the Google Cloud Console
    • You can create a Service Account by going to the Google Cloud Console, go to “APIs & auth” -> “Credentials”, then click “Add Credential” and “Service Account”, finally clicking “JSON” to download the JSON key.
  • Encrypting the JSON key
    • Install the travis command-line utils: sudo gem install travis -v 1.8.0 --no-rdoc --no-ri
    • run: cd your_website_dir
    • run: cp path/to/downloaded/cloud/service_account.json .
    • run: travis login --auto
    • run: travis encrypt-file service_account.json --add
    • run: rm service_account.json
      • DO NOT check this file in! Only check in the encrypted version.
  • My .travis.yml file which kicks off the deploy script
    • Grab this, and add it to your project (or, diff it with your existing .travis.yml file and add the relevant lines).
  • My travis.sh script which is the actual deploy script
    • This has the logic to download the Google Cloud SDK, configuration authentication, and perform the actual deploy.
  • My app.yaml which configures my app for App Engine
    • I had to remove some values, in order to work with the new gcloud command. For example, I had to remove the application and version keys from this file (they are set in travis.sh now, via gcloud).
  • Turning on App Engine Admin API and Google Cloud Storage JSON API in the "API Manager" of the Google Cloud Console.
    • None of the docs I found told me to do this. Took me a while to figure this part out!

If you don't mind spending $60/year for hosting with a custom domain and SSL, consider Firebase. It's significantly less steps.

Popular posts from this blog

Lists and arrays in Dart

Converting Array to List in Scala

Null-aware operators in Dart