I no longer maintain any personal sites powered by WordPress. This site migrated to Jekyll in 2019. I held off on migrating my photography site because of the custom plugin used to pull images from Flickr. This plugin helped simplify sharing photos for posts, portfolios, and customer downloads. I uploaded photos to Flickr, set a metadata tag on the page/post with the Flickr photoset ID, and the plugin did the rest.
This worked well for years, despite the occasional caching issue. The plugin was relatively stable, and had the last significant change in April 2017. Everything went to hell in July of this year when the Flickr OAuth integration failed, preventing the plugin from downloading new data. I spent a couple days updating a dependent library and hacking around OAuth 1.0. Flickr doesn’t seem to care much about PHP, given the lack of an official client, and I never want to deal with OAuth 1.0 again. This was the first sign that I needed to find a better solution.
The next was an email from Let’s Encrypt reminding me to update SSL certificates by the end of September. It turns out certbot had been crashing for a while, and not updating the certificates. How did we get here?
Many years ago when I set up the server on DigitalOcean, I opted to use CentOS 6.x since it had long term support, despite most of my server experience being with Ubuntu. I setup this server in 2013 when I was just learning about infrastructure as code, so I used Vagrant+Salt to configure it. I later became proficient in Terraform and Ansible while working at edx, but never incorporated this knowledge into my one server because the cost—my time—outweighed the benefits. As time went on, Python 2.7 was deprecated and my certbot grew outdated, hence no certificates. I tried installing Python 3.x, but ran into OpenSSL issues.
I could have simply created a new droplet, copied data, and been fine; but, I don’t want to deal with servers anymore. I don’t want to think about keeping them secure, doing software updates, etc. I just want to focus on posting my photos.
I decided to finally migrate to a static site. The Flickr plugin can be replaced by static images, and I found that clients are perfectly fine receiving a Dropbox link with their photos.
The migration took place in a few phases:
Exporting data is pretty straightforward using the Jekyll Exporter WordPress plugin. Many of the posts needed to be reformatted to correct line breaks, fix broken HTML, and remove WordPress shortcodes. Some of this was automated via WebStorm features and find+replace with regex; however, I still had to manually modify many posts.
I learned from my previous migrations to start with a theme first (which is the opposite of how I normally work). This is especially important for a photo-heavy site because the theme influences how the photos are displayed (e.g., resolutions, aspect ratios, overlays). My previous design had a heavy focus on full screen photos. The homepage was a fullscreen slideshow. Clicking on images in portfolio pages or posts also opened to slideshows. I wanted to maintain this focus, but also wanted to get away from the look and feel of Bootstrap 2.x.
I did not want to design and (poorly) maintain my own theme again. I’m perfectly fine paying $19 to avoid hours of work! I searched many theme sites, identified a few finalists, and settled on Gleam. This theme highlights photos in both galleries and slideshows, and offers a variety of page layouts. Unfortunately, there is no Jekyll variant of the theme, so I had to create Jekyll layouts and includes from the provided HTML files. This was tedious but still cheaper than starting from scratch.
Once the basic site was up and running, with placeholder images, it was time to add the images.
Importing images was the more difficult part of this migration. Almost all of my photos are in Lightroom spread across numerous folders. My photography site evolved from a personal blog I started at MIT in 2006, and now has 167 posts. Matching all of these posts to folders in Lightroom is a tedious task, and not really worth the hassle for anything prior to 2010 (when I got more serious about photography). This left me with the most ironic option: build yet another Flickr plugin.
flickr_downloader, does the following:
flickr_photoset_idvalue from the front matter on all posts and pages.
The YAML file also serves as a record of which photo sets have been downloaded, helping to avoid unnecessarily re-downloading images.
A separate plugin is used to render the main image for each post. This image is the first image that readers see at the top of a post or page, or when viewing a list of posts. It’s also the image used when rendering previews for posts shared via social media. The plugin either picks the main image for the post’s associated Flickr photoset, or falls back to the image specified via the
image value in the post’s frontmatter.
Image galleries are rendered using the data in the YAML file to point to the image location on disk, and determine the appropriate
title attribute values based on the image title and description. This was achievable with simple Liquid templating, so no plugin needed.
I decided to publish these together at https://rubygems.org/gems/jekyll-flickr-utils. The README includes some example usages.
Building this plugin was much easier in Ruby than PHP given (a) there is a Ruby Flickr SDK with more active development, and (b) I find it far easier to develop with Ruby than PHP and WordPress code. I sincerely hope this is the last time I ever need to use the Flickr API.
I somewhat care about PageSpeed, so I serve responsive WebP versions of my sites’ images. Jekyll Picture Tag simplifies much of this, and I use it on this site. It builds in seconds given the minimal content. The photography site hosts 2615 images across 136 galleries. It takes about 4 minutes to render from scratch on my M1 Max with 64GB of memory. I’m su
I’ve typically cared about build times for my sites because I don’t post frequently. Netlify forced me to care because the photography site exceeded their 30 minute build time limit. I explored alternative hosts such as Render and Cloudflare, but none offered incremental builds. I even rebuilt some of the site in Hugo before giving up in frustration—the docs are lacking. Ultimately, I discovered a Jekyll build cache plugin for Netlify. The overall build time is around 5 minutes, with only half of that consumed by the actual Jekyll build.
Note that I was tempted to host from an AWS/GCP bucket, but I remembered that my desire to minimize ops work is what prompted this project in the first place. I don’t want to think about DNS or SSL certificates. I will gladly let Netlify do that for me.
I’m completely serverless, and much happier for it!