This is My Blog on Docker + IPython
July 13, 2014
Late last year, I decided to refresh my blog with a more responsive design. In doing so, I looked for ways to simplify my blogofile setup. I looked at Wintersmith, Pelican, and PyGreen but in the end decided to roll my own: five Mako templates, 170 lines of Python, and my posts in Markdown. I was pleased. Mostly. Two aspects of my generator nagged me, both of which I corrected this past weekend.
First, my simple script had not-so-simple dependencies: the Mako, Markdown, and Pygments Python packages; a local webserver to preview the rendered site; and rsync to upload the generated site to my webhost. Originally, I setup my local box with all of these, choosing to "pay-later" should I get a new computer, have to restore my box, want to post from another machine, etc. Now eight months on, I decided to pay-down this technical debt by creating a Docker image that packages everything together using a simple Dockerfile:
FROM ubuntu:14.04 MAINTAINER Peter Parente <[email protected]> RUN apt-get update RUN apt-get -yq install python-pip openssh-client rsync RUN pip install Mako==0.9.1 Markdown==2.4 Pygments==1.6 ADD . /srv/blog WORKDIR /srv/blog
I drive the build and use of the image from a convenient Makefile in my blog git repo.
# build the docker image once make build # render my blog posts acessbile via a contiainer-host mount # then run a Python SimpleHTTPServer to view the results locally make render # render and rsync the content to my webhost make publish
Now rendering, previewing, and uploading my blog requires Docker and, optionally, make. That's it.
Second, I felt both liberated and limited by Markdown-only postings. I say liberated because writing in Markdown beat the heck out of writing pure HTML or using some WYSIWYG editor, especially for postings laden with code. I say limited because I missed the richness of explanation available in another tool I'd been using daily for over a year now, IPython Notebook. To quiesce the latter feeling, I decided to jump on the bandwagon and support both pure Markdown files and IPython Notebooks as blog posts.
The addition of a couple dependencies in my Dockerfile, the ballooning of my generator code to a massive 250 lines of Python, and the creation of a new template and stylesheet enabled the blog post you see before you.
And now, an amazing demonstration of IPython-powered posts ...
First, install the Humor Sans font.
!wget http://antiyawn.com/uploads/Humor-Sans-1.0.ttf -O ~/.fonts/Humor\ Sans.ttf
--2014-07-14 02:00:41-- http://antiyawn.com/uploads/Humor-Sans-1.0.ttf Resolving antiyawn.com (antiyawn.com)... 184.108.40.206 Connecting to antiyawn.com (antiyawn.com)|220.127.116.11|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 25832 (25K) [text/plain] Saving to: ‘/root/.fonts/Humor Sans.ttf’ 100%[======================================>] 25,832 136KB/s in 0.2s 2014-07-14 02:00:41 (136 KB/s) - ‘/root/.fonts/Humor Sans.ttf’ saved [25832/25832]
Next, flush the matplotlib font cache.
import matplotlib.pyplot as plt plt.ioff()
<matplotlib.rc_context at 0x7f39fe924d90>
fig = plt.figure(figsize=(10,5)) ax = fig.add_subplot(1, 1, 1) ax.bar([-0.125, 1.0-0.125], [0, 1], 0.25) ax.spines['right'].set_color('none') ax.spines['top'].set_color('none') ax.xaxis.set_ticks_position('bottom') ax.set_xticks([0, 1]) ax.set_xlim([-0.5, 1.5]) ax.set_ylim([0, 2]) ax.set_xticklabels(['Before IPython support', 'After IPython support']) plt.yticks([0, 1, 2]) plt.title("Useless plots on this blog")
<matplotlib.text.Text at 0x7f39fe8340d0>
The future is bright, I tell you.
So I've scratched my two blog itches, and, as expected from itching, have created more. The fact that my blog generator is now in a portable, reusable container yet still somewhat hardcoded to this site bugs me. With a bit more elbow grease, I believe I can make a Docker image that can seed a blog like mine for any purpose simply by setting a few environment variables.
When or whether I get around to scratching this itch is an open question. Meanwhile, I solemnly promise never to write another veribified heading on this blog (but I refuse to make a similar promise for xkcd-style plots).