When I decided to make my kawashi.me 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.
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.
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.
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
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
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.
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
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:
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 AWS access 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”.
Your site should now be accessible using your domain name.
Just remember that since you are 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.