Basically I just wanted to write posts in Markdown and have something convert it into a pretty HTML page based on some template. Luckily, such a software already exists.

Note: This blog no longer uses the method described here. While a static site is easy to make and quite cheap to maintain, I wanted to learn more about web frameworks and how to connect them to databases in the cloud. Because of that, this blog is being served to you via Flask running on Google's App Engine standard environment. When I get some free time, I want to write how easy it was to start, yet mind-numbingly frustrating it get everything together.

Called static site generators, they read content formatted in Restructured Text or Markdown and generate the formatted page based on a template. One of the most popular static site generators is a Python-based tools called Pelican.

Basics

To host a static website online, you would need the following:

  • HTML files Generated by Pelican
  • A domain name which you can change the nameserver (Most registrars let you do this I think)
  • A place to store the files and make them publicly accessible - Amazon S3
  • Some way to point your domain name - CloudFlare

I’ve read a bunch of articles detailing how to run a static-site blog using Pelican and Amazon S3 but no single one really contained all the information to get a site up and running from scratch. And most of them use Amazon Route53 or Cloudfront to route the domain name.

Here, we take advantage of the free tier of Cloudflare to provide us the routing functionality of Route53 and the content distribution of Cloudfront. As an added bonus, CloudFlare’s free plan also provides a thin layer of security that can help deal with DDoS-style attacks.

Install and configure Pelican

First, set up a virtual environment in Python using virtualenv or Anaconda. Remember to use Python 2.7 in your virtual environment because a program we will be using later called s3_cmd is not Python 3.x compatible.

Lets install Pelican via pip. I also suggest to install Markdown and typogrify.

$ pip install pelican Markdown typogrify

After installing, create a folder that will contain the local version of your blog. Go to folder you just made and set up Pelican by typing pelican-quickstart. This will create a files that will we will use to publish upload to Amazon S3 later.

$ mkdir my_blog
$ cd my_blog
$ pelican-quickstart

Next, you will be presented with a series of questions to set up Pelican. Let’s assume your folder is located in /Users/Kent/my_blog and that the domain name you will use for this site is myblog.com. Here’s a summary of the questions and how you should answer them.

> Where do you want to create your new web site? [.] .
> What will be the title of this web site? My Blog
> Who will be the author of this web site? Your Name
> What will be the default language of this web site? [en]
> Do you want to specify a URL prefix? e.g., http://example.com   (Y/n) n
> Do you want to enable article pagination? (Y/n) n
> Do you want to generate a Fabfile/Makefile to automate generation and publishing? (Y/n) Y
> Do you want an auto-reload & simpleHTTP script to assist with theme and site development? (Y/n) Y
> Do you want to upload your website using FTP? (y/N) N
> Do you want to upload your website using SSH? (y/N) N
> Do you want to upload your website using Dropbox? (y/N) N
> Do you want to upload your website using S3? (y/N) y
> What is the name of your S3 bucket? [my_s3_bucket] myblog.com
> Do you want to upload your website using Rackspace Cloud Files? (y/N) N
> Do you want to upload your website using GitHub Pages? (y/N) N
Done. Your new project is available at /Users/Kent/my_blog

Create content and test Pelican locally

Before deploying to S3, let’s see if Pelican is working properly. To do that, you will need to post an article.

In Pelican, articles are written in Markdown or ReStructured Text which is converted by Pelican to HTML when you publish. Personally I prefer writing in Markdown so here’s a sample post showing the the different parts of an article.

Title: How to host a blog using Pelican, Amazon S3, and Cloudflare
Date: 2016-10-12 21:07
Category: How-to
Tags: howto, aws, pelican, cloudflare, python, web
Summary: Let me tell you how I set up this blog using a 
static site generator called Pelican, and used Amazon S3 
and Cloudflare to store the generated HTML files and route 
my domain name to the static files respectively.
Status: draft

When I decided to make this blog, I looked into setting up 
a virtual private server or a cloud service to host it. 
However, these services seemed too complicated for what 
I wanted to do and didn't seem to be worth the time and 
money. 

Note the line “Status: draft” in the text. By default, Pelican will publish everything in the content folder. However, by including this line, this allows you to start writing a post and not worry that it will be published when you update your site. Just make sure to remove the “Status: draft” line when you are ready to publish.

Save your post in your_pelican_directory/content/your-title.md. After saving, you can view your site by running Pelican’s built-in development server.

$ make devserver

To view your site, go to http://localhost:8000 and see if it works.

If the layout of your site appears to be broken, try turning on relative URLs by modifying pelicanconf.py. Look for the following line

# Uncomment following line if you want document-relative URLs when developing
#RELATIVE_URLS = True

To stop the development server, type in

$ make stopserver

Set up S3 and connect with Pelican

The next step assumes you already have an Amazon Web Services account. If you don’t, sign up at for an AWS account and get some free credits for S3.

Sign in to your AWS account and go to the S3 Management Console. Create two buckets after the domain name of your site and name them:

  • www.myblog.com (or www.yourdomain.com)
  • myblog.com (or yourdomain.com)

Remember to change myblog.com with your own domain name. To enable static site hosting, we will make one bucket serve all the files and the other bucket to redirect to it.

For example, we want to access out site mainly through myblog.com and www.myblog.com to redirect to myblog.com.

  1. Select the myblog.com bucket and click “Properties”.
  2. From the panel, click “Static Website Hosting” and select “Enable website hosting”.
  3. Fill in “index.html” for the Index Document.
  4. Finally, look for the “Endpoint” URL of this bucket and write it down. You will need this later when setting up CloudFlare.

Now add a redirect for “www.myblog.com”.

  1. Go back to the top page of the S3 console, click “www.myblog.com” and click Properties.
  2. Click “Static Website Hosting” and select “Redirect all requests to another host name”.
  3. On “Redirect all requests to”, fill in the blank with “myblog.com”.
  4. Lastly, take note of the “Endpoint” URL of this bucket.

Your S3 buckets are now ready to serve static web pages. To connect S3 with Pelican, we will use a command-line tool called s3_cmd to automate the workflow. First, install s3_cmd using pip.

$ pip install s3_cmd

To enable s3_cmd to access your S3 account, you will need to give it an AWS access key and its corresponding secret access key to authenticate with AWS. These can be generated by creating an AWS IAM user and giving the identity you created access to your S3 account. As an additional layer of security, s3_cmd recommends using an encryption program like gpg to encrypt the AWSaccess key and secret access key.

Let’s configure s3_cmd.

$ s3cmd --configure

You are now ready to upload your Pelican blog to S3. To do this, simply type

$ make s3_upload

The first time you upload will probably take a while because everything has to be generated for the first time. In succeeding updates, Pelican and s3_cmd will only generate and upload the new and modified entries.

Your site is now online! You can access your site using the endpoint URL of “myblog.com”. But we don’t really want to type in myblog.com.s3-website-us-east-1.amazonaws.com everytime. For the last step, let’s connect your domain name to your S3 bucket.

Configure your domain name to use CloudFlare and connect to S3

Sign up for a “free website” account with CloudFlare. Then, log in to your registrar and change the current nameservers with ones CloudFlare provides.

Once CloudFlare has detected that your domain name is now using their nameservers, do the following steps

  1. Go to the CloudFlare Management Console and select “DNS”.
  2. Create a CNAME entry for the myblog.com bucket. For example, enter “myblog.com” in “Name” and “myblog.com.s3-website-us-east-1.amazonaws.com” in “Domain name”.
  3. Create another CNAME entry for www.myblog.com. For example, enter “www.myblog.com” in “Name” and “www.myblog.com.s3-website-us-east-1.amazonaws.com” in “Domain name”.

Congratulations!

Your site should now be accessible using your domain name.

Just remember that since you now using a Content Distribution Network (CloudFlare), there will be times where minute changes (when developing for example) will not be reflected immediately because you might be looking at a cached version. If you are encounter such problems, go to the CloudFlare console and change to “Development Mode” via the quick actions menu.

Other resources

Setting up a blog with Pelican and Amazon S3

Setting up a Pelican site under your own domain using Amazon S3

Python’s killer apps for blogging: Pelican and S3cmd