I have been running my blog on Wordpress for almost a year now and although it is a great blogging platform I have hit a few hiccups along the way which have led me to want to change my tactics. My primary concerns were a recent attack on the XMLRPC API which although no access was gained left my webserver limping along and took the website offline for a few hours until I checked the logs and added the offending IPs to the deny list. I also noticed alot of unwanted probing traffic looking for stuff like certain plugins or trying to establish the Wordpress version number, presumably so they could exploit one of the security flaws in the many CVEs we have seen against Wordpress. Combined with the constant need for updates, the general resource hogging and the fact the only real advantage to Wordpress over static files was the ability for readers to leave comments of which 99% were spam anyway I decided it was a good time to ditch Wordpress and go for a leaner alternative.
Say hello to Pelican, a Python based static page generator which can generate static HTML pages from reStructuredText markup files into a variety of themes using Jinja2 for templating. This had a number of advantages for me including:
- Simple to use reStructuredText markup for posts.
- Can be version controlled in a git repo.
- Jenkins can run a make file on merge to generate the site content.
- As the site is static it can easily be hosted on S3 with CloudFront, no more managing LAMP stack servers.
- No database required.
- Can still do commenting / discussion using Disquis.
- Site will be blazing fast compared to Wordpress equivalent.
First off I setup a virtualenv on my host and installed Pelican from PyPi, I then ran the pelican-quickstart command to generate a base project for my blog. Pelican naturally organises the site into articles (blog posts) and pages, but of course it is flexible if you wish to use it more as a CMS by just having pages and no articles. Next I configured a git repo and performed an initial commit of the empty Pelican project and ran the make file with the html arguement to check I could generate a blank site.
Unfortunately the default theme in Pelican wasn't really to my taste and I am a terrible designer so I went in search of some alternative themes, luckily there is a big fat GitHub repo full of them and there are some really tasty ones over at https://github.com/getpelican/pelican-themes. A site containing a preview of all the themes was available in the README.md, after a few minutes looking through the screenshots I found one I liked and I cloned it to my blog's git repository, a breif modification to pelicanconf.py and rerunning make generated the site with the theme I choose.
Much better, now on to writing content.
All content in Pelican is in reStructuredText markdown, although other forms of markdown can be used if they have the correct parser installed in your Python env. Within the Pelican project is a content folder, inside this folder you can put .rst files which will get generated into articles or blog posts. You can also make pages by placing rst files in content/pages. When the static pages are generated all rst files in the content folder will be considered and generated into HTML pages, they are also sorted by date, tags and category and relevant index files are also generated to allow your visitors to easily navigate your site. Each article must start with a title, date, and any other meta data which helps identify the article. I created a template.rst file which I can easily copy into the content folder and rename accordingly, here is the template:
This is the title! ################## :date: 2000-01-01 12:00 :category: Technology :tags: internet, electronics, technology Put your content here :-).
Lets create a simple hello world inspired rst and dump it in the content folder and rerun the make file to check it all works ok...
Seems to work great, there are some tweaks I'd like to make to the theme such as adding Google Adsense and Analytics but lets worry about that later, for now there is a bigger task, converting all my old Wordpress posts into rst files.
Converting Wordpress Posts to Pelican
It would be reasonable to assume I wasn't the first person to go on this static page blog journey and I turned to Github to see if anyone had an easy way to convert Wordpress to rst, turns out Lawrence Carvalho had just the thing over at https://github.com/lawrencec/wordpress_to_rst, so I exported my posts from Wordpress using the export feature and ran the script against the resulting xml file.
It worked reasonably well but I had to do some manual clean up on some of the posts, luckily I didn't have too many as I typically only post a couple entries a month, once these were sorted I regenerated the site to check it all looked ok and then commited to my git repository.
A little bit of CI magic
Now I had my posts imported and the rst files, make scripts, theme and config file stowed safely in my git repository I turned to automating the deployment of the site when I merged a new rst file (blog post) into the repository. For this task I will use everyone's favourite CI tool, Jenkins.
The config is super simple, it literally polls the Github repo using SCM polling once per hour for changes on the master branch, if there is a change it runs a build using the pyenv plugin to create a Python virtualenv to seggregate the blog build from my other Python pproject builds and then executes the make file followed by SCPing the output files to the webserver (this can be switched out for Amazon S3 or Rackspace Cloud Files).
After configuration I hit the run button and once the job had completed checked the website URL, sure enough my latest post was now visible live on the web.
As you can see using Pelican to write, version control and publish your blog is super easy and comes without the overheads of running Wordpress. I am yet to decide if I'll integrate Disqus etc... into the blog as I never received too many comments anyway. My next step will be to move the blog from my local webserver running Apache onto S3 or Rackspace Cloud Files along with some CDN front end, this should make the site super speedy and far more fault tolerant than its current configuraton. Regrettably before I tore down my Wordpress install I forgot to do some performance tests for comparison, although it stands within reason some basic HTML pages which are mostly CSS for presentation will out perform a bunch of heavy PHP scripts.