osteel's blog Web development resources

Install and deploy a Pelican blog using Fabric - Part 2: installation and configuration

Been here before?

You can also subscribe to the RSS or Atom feed, or follow me on Twitter.

In part 1, we set up a local environment containing everything Pelican requires to run properly.

Let's move on to the installation and configuration of Pelican itself.


Pelican installation

If you are using The Vagrant config provided in part 1, start the "local" box and ssh it if it is not already the case:

vagrant up local
vagrant ssh local

Then, activate the Virtual Environment:

workon blog

Go to the directory you want your blog to reside in (if you are using Vagrant, this is "/vagrant") and type:

pip install pelican

Pelican allows to use either reStructuredText or Markdown formats for your articles. I personally use Markdown, but the choice is up to you.
You can also use plain HTML if that's your thing.

Install your weapon of choice:

pip install Markdown

Now is a good time to save our current list of dependencies. Type this:

pip freeze

This command will give you the list of the packages that are installed in your VE. It should more or less look like this:


pip allows you to save this list into a file, in order to quickly reinstall its content if you need to (on another machine, for example):

pip freeze > requirements.txt

All you need to do to reinstall this environment somewhere else is:

pip install -r requirements.txt


Now let's set up the skeleton for your blog using the built-in wizard:


Pelican will now ask you a series of questions. Some of them have a value between square brackets at the end: this is the default value you can select simply hitting return.

I will only list the questions that might be a bit confusing here:

Do you want to specify a URL prefix? e.g., http://example.com   (Y/n)

Only if you already have a domain name that will point to your blog. You will be able to update this later directly in the publish config file.

Do you want to generate a Fabfile/Makefile to automate generation and publishing? (Y/n)
Do you want an auto-reload & simpleHTTP script to assist with theme and site development? (Y/n)

Answer "Yes" to both, these are functionalities we are going to use.

Then say "No" to all the different means to upload your blog. You might end up wanting to use one of the listed methods, but they are not covered in this article.

Done. Your new project is available at /vagrant


Now let's have a glance at the default look of the blog. Type this:

fab build


fab serve

You've just launched a local webserver, that uses the port 8000 by default. Open your browser and navigate to http://localhost:8000: the default skeleton and template should display (this also works with the Vagrant box because we activated the port forwarding option, cf the Vagrantfile in the Vagrant way section).

"Default theme"

That was easy, wasn't it?

Interrupt the server and regain control of your terminal typing ctrl + c.

fab build and fab serve are Fabric commands. The first one generates the HTML content (more on this in the next section) and the second one creates the server. You can also use the shortcut command fab reserve that runs both ones in turn.

Fabric is not the only way to generate content, spawn a HTTP server etc. You can read more about that in the online documentation.
Here I choose to use Fabric simply because this is also what we are going to use for pubication later on. Better get familiar with it right now.

I will give more details about it in part 3.

Writing content

How about actually writing something now?

Create a file in the "content" folder, something like "my-first-post.md" (put the appropriate extension if you didn't go for Markdown). Add some content in it, following this format at the beginning:

Author: osteel
Title: My first post!
Date: 2015-02-22
Slug: my-first-post
Category: test

##A subtitle

Some **Markdown** content, with some *formatting*.

A list:

 - Milk
 - Butter
 - Eggs


Pelican will analyze the first lines to properly generate the post. Rebuild and serve your blog with fab reserve, and reload http://localhost:8000: you should see your post.

The generated HTML files are put into the "output" folder. A "test" category was automatically created and placed in the header (if you had specified none, it would have created a category called "misc" by default).

This is basically how to write articles. Pelican also allows to create static pages that are not posts (typically, the "about" or "contact" pages). Simply add a "pages" folder under "content", and edit a "about.md" file:

Title: About
Slug: about

Amazing blog.

Regenerate the content and refresh the web page: a new "about" entry has been placed in the header.

These are the very basics of writing content. You probably wonder how to tweak the template to your taste now. Don't worry, we are getting there.

But first, let's pick a theme!


The default theme is nice, but chances are you will want to change it.

Pelican comes with a variety of themes to choose among the official repository ones or custom ones made by various people.

I am not going to invent much here and will mostly follow the instructions available on the repository's page.

First, clone all the themes in a local directory (if you are using the Vagrant box, you will probably want to install Git now - sudo apt-get install -y git-core):

git clone --recursive https://github.com/getpelican/pelican-themes ~/pelican-themes

Then, open the "pelicanconf.py" file and add these lines at the end (change "vagrant" for the correct username if necessary):

# Theme
THEME = "/home/vagrant/pelican-themes/mnmlist"

Rebuild and serve:

fab reserve

Reload http://localhost:8000: you are now looking at the "mnmlist" theme!

Test as many themes as you like until you find one that suits you. I personally went for the Octopress one, ported from Octopress by Maurizio Sambati.

Once you picked one, copy its content in a new "theme" folder in your blog's directory:

mkdir theme
cp -rf ~/pelican-themes/mnmlist/* theme/

Edit "pelicanconf.py" again and change the value of "THEME" for the new location:

THEME = "theme"

Rebuild and refresh to make sure it worked.

You can now remove the other themes:

rm -rf ~/pelican-themes

Most of the themes have their own settings. Just have look at the theme's own README file to know what they are (here is the "mnmlist" one, for example).


We had a quick preview of the configuration in the previous section, when we changed the theme's path. Pelican actually has two configuration files: "pelicanconf.py", with whom we made acquaintance already, and "publishconf.py", which contains production-wise settings.

The latter should contain settings that are relevant to your live environment only; we will see examples later on.

Your "pelicanconf.py" file should currently look like something like that:

#!/usr/bin/env python
# -*- coding: utf-8 -*- #
from __future__ import unicode_literals

AUTHOR = u'osteel'
SITENAME = u'My Blog'

PATH = 'content'

TIMEZONE = 'Europe/Paris'


# Feed generation is usually not desired when developing

# Blogroll
LINKS = (('Pelican', 'http://getpelican.com/'),
         ('Python.org', 'http://python.org/'),
         ('Jinja2', 'http://jinja.pocoo.org/'),
         ('You can modify those links in your config file', '#'),)

# Social widget
SOCIAL = (('You can add links in your config file', '#'),
          ('Another social link', '#'),)


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

# Theme
THEME = "theme"

Most of the parameters are pretty straightforward, and I invite you to have a look at the documentation that describes them all.

I am going to focus on specific areas: URLs, plugins and comments.


For now, our posts' URLs look like so:


We are going to change this to adopt a format like the one I am using for my blog:


Obtaining this result is pretty easy. Open the "pelicanconf.py" file and add these lines:

# URLs
ARTICLE_URL = 'posts/{date:%Y}/{date:%m}/{date:%d}/{slug}.html'
ARTICLE_SAVE_AS = 'posts/{date:%Y}/{date:%m}/{date:%d}/{slug}.html'

Now, let's move the post we created earlier in a folder reflecting this structure. Go to the "content" folder and create subfolders as following (change the date if you want to):

cd content
mkdir 2015 2015/02 2015/02/22

Then move the post:

mv my-first-post.md 2015/02/22

Rebuild and refresh: URLs are now a bit more structured.

Of course, this is just an example, and you are free to adopt any format you want.


Pelican supports plugins since its version 3.0, allowing to add functionalities without having to touch the core. Plugins are maintained in a separate repository just like the themes.

You will find a description of each one of them there, and we are going to manage them the same way we did for the themes.

git clone them all locally, and copy over those you want in a new "plugins" folder in your blog's directory. If you want to use the Liquid Tags plugin for example, this is how you would do:

git clone https://github.com/getpelican/pelican-plugins ~/pelican-plugins
mkdir plugins
cp -rf ~/pelican-plugins/liquid_tags plugins/

Open "pelicanconf.py" and add these lines at the end:

# Plugins
PLUGIN_PATHS = ['plugins']
PLUGINS = ['liquid_tags']

Pelican now knows where to find the plugins and which ones to load.

Rebuild and refresh.

Copy as many plugins as you like, update the config file accordingly and, when you are done, delete the other ones:

rm -rf ~/pelican-plugins


Pelican natively supports Disqus, a third party service that will take care of your commenting system for free, externally (nothing to host).

Head to the website and create an account. Set it up as you like and note your sitename, which is just the string before ".disqus" in the URL of your account.
For example, mine is "https://osteel.disqus.com", so my sitename is "osteel".

Now edit "pelicanconf.py" and add the following line (with the right sitename, of course):


Build, serve and refresh: you should have a nice comment box at the bottom of your article.

Note: We added this config parameter to "pelicanconf.py" so you could see the result straight away, but this actually only relevant in the context of your live environment (Disqus won't recognize your local URL). This is typically one of the settings that should be in the other config file, "publishconf.py".

That's it for today. In part 3, we will see how to use Fabric to automate the provisioning of a server and the publication of new content.

Enjoying the content?

You can also subscribe to the RSS or Atom feed, or follow me on Twitter.

Last updated by osteel on :: [ vagrant fabric tutorial python blog pelican ]