Personal website with password protection11 May 2020
After numerous attempts at finding a cheap and easy solution to making a password protected static website, I finally have settled my mind on one! Before going over the solution let me go over the requirements that I had in my mind for the website:
- Static and blog-aware
- Password protection on a part of the website
- Smooth and easy workflow to move content from private part to public
- Preferably, an automatic CI/CD
I tried multiple solutions such as setting up Heroku dynos, CloudCanon etc. None of the solutions satisfied all the requirements until I found this option:
GitHub + Jekyll + Makefile + AWS S3 + AWS Lambda
Let me paint a high level picture of how the setup looks like:
Two GitHub Repositories
Website content is split into two parts: public and private repositories. The public repository works like any other static website hosted on GitHub.
It contains all the jekyll build material and public posts. Private repository only contains posts that are private.
Public Repository Hosting
The public repository gets hosted on GitHub pages as any other static website. This takes care of the public part of the website.
Setting up private part is slightly complex but it’s a one-time effort. I’ll try to provide a high-level overview how that works.
The private content is hosted in an AWS S3 bucket which only allows AWS CloudFront to read the contents. I then setup AWS Lambda that runs when a viewer tries to read content via CloudFront distribution. Here’s a step-by-step tutorial on how to set up S3 and CloudFront.
Building Private Website
In order to build the private website, we are going to need both the public and
private repositories. After cloning the public repository, we create a directory
<public_repo>/_posts_private and clone the private repository in
it. Yeah, we could have used git submodules. But, given that the
_posts_private should point to a private repository, if we use submodules, it
will break GitHub’s CI/CD for the public website. We don’t want that to
break. So, we manually clone the private repository inside
folder. The magic happens inside the
||Build private website|
||Build public website|
||Build and run private website locally|
||Build and run public website locally|
||Update private repository on S3|
make sync, we can see that the private part of the website is
published to S3/CloudFront. If you try to access it via CloudFront URL, you’ll
see that a dialog pops up asking for your username and password.
Tying Private and Public Repositories Together
Ok so we now have public part of the website working on GitHub pages and the
private part of the website working on S3/CloudFront. We are now going to tie
them together using a custom domain name! Domain names are pretty cheap
(10-20$/yr). So, what I did was I bought this domain name and configured the DNS
harshad.me points to the GitHub URL and
to cloudfront URL. Here’s how the DNS entries look: