Pelican, pyenv, Poetry, and (Github) Pages

As I mentioned in my last post, I'm using Pelican to set up this new blog. It's not yet properly themed, it's missing all of the historical posts, and there's a lot more config I need to play with. And I need to finish the domain config.

But it's up. And you know this because you're reading it.

There are ton of "how I built this" pages out there, esp for static blog sites like Pelican, but I'm writing this up in case any piece of it helps someone in the future.

pyenv and Poetry

While I have 13+ years of Python experience, I've spent the last 5 years as a VP of Engineering letting my day-to-day coding chops rust. I'm aware of the latest discussions around dependency management and deployment, and I particularly know Docker (since Appsembler's main virtual labs product is container-based). But my muscle memory is still based on virtualenv and pip.

So I thought for this one, I'd give pyenv and Poetry a try.

I've got a new M1 Mac Mini, so first step was to get something newer than python 2.7 installed. pyenv makes that incredibly easy... after you install Homebrew, of course.

# Homebrew, work your magic
$ brew update
$ brew install pyenv

# Install something more modern than 2.7 (3.9.5 is lastest as of today)
$ pyenv init
$ pyenv install 3.9.5
$ pyenv versions
* system (set by /Users/abeals/.pyenv/version)

# Let's set 3.9.5 as the default
$ pyenv global 3.9.5
$ pyenv versions
* 3.9.5 (set by /Users/abeals/.pyenv/version)

Then add this line to your .zshrc file and restart your shell:

eval "$(pyenv init -)"

I won't write out the Poetry installation, because (a) the docs are quite good, and (b) they're likely to change in the time between my reading this and you reading it. In fact, I ended up in a weird pre-1.2.0 state where the script told me that I was using the wrong version, and wouldn't be able to upgrade later. I uninstalled, changed the web docs from 1.1 to master, and ran the installer instead. Still got the 1.2.0 "you won't be able to upgrade" error because 1.2.0 isn't officially released.

In my limited usage, Poetry worked well. For Pelican, I didn't have to do any fancy dependencies, nor did I get to leverage the different dev and prod environments that Poetry offers. It would have helped me back in 2008, though.

Side note

A while back, I considered a Docker-based workflow, and may even get there soon, since I have multiple git repos involved, need to coordinate pushes, etc. It would be nice to remove the deployment workflow from my local machine if possible.


Pelican is a static site generator. It's been around for a surprisingly long time (or perhaps I'm just old), so it has a good track record and solid community behind it.

I chose it due to my comfort level with Python, mainly for deployment. Also helps in case I ever do get to hacking the framework or building a plugin (doubtful).

It has first-class Markdown support, code syntax highlighting, and built-in Atom/RSS feeds. The plugins and themes ecosystems are pretty solid. But it doesn't offer too many bells and whistles right out of the box -- so it was the level of simplicity that I needed.

I want to focus on writing.

Github Pages

I originally planned to self-host, and I may still, but it's hard to turn down the ease of use from Github Pages. We spend much of our days in Github for work already, so I'm used to the platform.

It's free, easy to use, and is well-documented. If traffic goes up or I need other functionality, I can easily move it.

Pages is very, very easy. Set up a new repo with some options checked. Clone it locally. Drop your Pelican /output directory contents into your local repo, push to origin, and that's it.


At first, the fonts didn't load. The rest of the CSS seemed to, so I assumed it was either a @font-face issue with Github Pages, or absolute/relative path problem. Stackoverflow searches turned up answers in this vein. However, the paths looked OK, and some CSS did load. Using Firefox's console, I saw 404s coming from 3 out of 6 CSS files in one directory. I confirmed that direct access of those CSS files returned 404s, even though the files were present and accessible in the repo through the normal Github UI.

Then I hit on a comment that said sometimes Pages' Jekyll processing missed files in a directory starting with an underscore. I didn't have that problem -- as I mentioned, 3 of 6 files in the directory were accessible. But I thought maybe Jekyll needed a kick. So I tried adding a .nojekyll file to the root, which (a) would prevent that underscore issue for the future, and (b) kicked the Pages processing to re-eval the repo. Worked like a charm.

Unfortunately, I don't know which one solved the problem: pushing a commit of any sort, or adding the .nojekyll file in particular. I'll try removing the file in an upcoming update and see what happens.

Current Janky Workflow

I'm writing in iA Writer, then I have a private git repo in Keybase for my source files, Pelican config, etc.

Right now, I copy the files I want to publish from iA's default destination (iCloud, which was a pain in the neck to find on disk, compared to Dropbox) to the private git repo. Once the files are there, I regenerate and run the local Pelican server to test it out:

$ pelican ./content
$ pelican --autoreload --listen

If everything looks good, I copy the contents of the output directory to my local copy of my Github Pages repo, commit, and push to origin.

So that's two repos, a virtual environment, and a lot of copying. I can (and will) be streamlining the workflow. But it works.

Resources / Acknowledgements: