Here’s my latest weekend project: How can I host a website for cheap without the need for a server, with 100% uptime, and while learning during the process?

The answer involves JS and a few AWS services.

This is a long one, and you might not want to do everything I’ve done, so I have separated this guide into independent sections.

Table of Contents

  1. Hexo
  2. S3
  3. CloudFront

Hexo

This blog is written on Hexo. The reason for this is because it is a very simple blogging platform that converts everything into static files for deployment. This is important because S3 does not render server-side code like PHP or Node.

Installing Hexo is really easy. All you need is npm installed.

1
2
3
4
5
npm install -g hexo-cli
hexo init myCoolNewBlog
cd myCoolNewBlog
npm install
hexo server

Ok, so you’ve run these commands but you probably have no idea what you’ve just done. If you visit the URL the last command printed to your terminal it should show you your new blog.
The first thing I did was download a new theme. There is a wide selection here. I am using Apollo. Once you download the theme, just stick it in the themes directory.

Now, you’ll want to take a look at two files. The first is the _config.yml in the root directory. This is where you change your theme and personalize your website. Most of these settings are straightforward. If you want a more detailed list, here’s the documentation.. The second is your theme’s _config.yml file. This contains theme-specific settings and should be very straightforward.

Writing a blog post is simple, to generate a post run hexo new <title>. This will create a markdown file in the source folder. If you haven’t used markdown before, there’s a great guide here.. Once you’re happy with your blog post you can convert it into static HTML with hexo generate.

Deploying with Hexo is also super easy. The command is hexo deploy, but you’ll need to specify where you want to deploy to in the _config.yml file. For S3 the format is the following:

1
2
3
4
5
deploy:
type: s3
bucket: myCoolBlog.com
aws_key: XXXXXXXXXXXXXXXXXX
aws_secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

S3

To deploy your hexo blog (or any static files) on a website hosted by S3, the first thing you need is a bucket. I have 2 buckets, one named www.keithcaulkins.com and the other keithcaulkins.com. This is so I can serve over both domains (note that www.keithcaulkins.com bucket is empty, I simply use a redirect. To do this you have to set up static website hosting as “Redirect requests”).

Make sure your buckets can be accessed by the public. I’m using this policy:

1
2
3
4
5
6
7
8
9
10
11
12
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::www.MyCoolBlog.com/*"
}
]
}

On your main bucket, go to the properties and click on “Static website hosting”. Select “Use this bucket to host a website” and put the index document as index.html. Hit save and you’re all done for now!

Next you’ll need to create a hosted zone in Route 53. Create one for your domain (e.g. keithcaulkins.com) and it should already have default NS and SOA records. Click “create record set” and choose an A type record. Click “yes” next to the Alias field and for the target put in the name of your bucket. If you decide to use CloudFront, this will be your CloudFront Distribution (e.g. xxxxxxxx.cloudfront.net).

If you want www. to redirect to the root domain like me, set up a CNAME record with the value of your base url (e.g. keithcaulkins.com).

CloudFront

CloudFront caches the crap out of static files and assets. It can get expensive quick but it’s worth knowing how to use!

All you need to do is create a new web distribution. Most of the settings can be left default, but the important one is setting the CNAMES correctly (e.g. www.keithcaulkins.com and keithcaulkins.com), and the origin path to {bucket_name}.s3-website-{region}.amazonaws.com. That’s it!

Bonus

SSL! AWS offers 100% free certificates for domains under Route 53. The service is called “Certificate Manager” and it’s one of the simpler AWS services to use. All you’ve got to do is click the “Request a Certificate” button, enter your domain name(s), and hit the blue continue button three times.

Once they approve your request, go back into cloudfront, click on your distribution, click the edit button, select the “Custom SSL certificate” radio button and then use the dropdown to select the certificate that you made. You can also set it so that you only serve HTTPS traffic by going to behaviors and selecting “Redirect HTTP to HTTPS”.

Thanks for reading, and check out the great company I work for, atLarge!