In the previous version of my photoblog I embedded all images in the directory of each post. This caused a few problems:

  • Generating the static site took very long.
  • The site folder is 2GB big, slowing down Git and GitHub.
  • There’s no way to generate an image based on the viewer (retina display, etc.)

For this new version I wanted fast compile times and a small site repo. This meant the images had to go.

Serving the images

I’m running this site on a 512MB DigitalOcean droplet that doesn’t run any dynamic content, it just serves static files with nginx. I needed something that could serve and possibly resize my images to the requested dimensions.

Initially I had written a small Ruby application that could process uploaded images and dynamically resize them when requested. It worked well for a small while, but then I kept hitting the memory limit of my Droplet. I also felt there was too much code involved in the uploading a processing part.

The switch to GO

At AppSignal we use GO for some of our webservers, because it’s really fast and doesn’t require any software on our servers except for nginx.

After an evening of searching for libraries on GitHub I found Matrioska, a thumbnail generator written in Go.

It works really simple, just point it to a directory with photos on your server and run it. You can request the original image, or have it resize the image by adding the required dimensions to the photo, for example: http://localhost:7000/foo.png becomes http://localhost:7000/foo-100x100.png

Adding a caching proxy

After this was running on my webserver, I had to solve another problem. Matrioska doesn’t cache the images, meaning if you request an image ten times, Matrioska needs to generate the thumbnail ten times. This takes up a lot of resources, especially on pages with dozens of photos.

Since I already use nginx to host my static site, I can use it’s caching mechanism to cache thumbnails for a period of time. If someone requests and image ten times, Matrioska only needs to render it once. The other nine times it’s served from nginx’s cache.

The following config tells nginx to cache everything returned by Matrioska for 30 days, with a maximum cache size of 5 Gigabytes.

This init script (/etc/init/matrioska.conf) tells Ubuntu to start Matrioska on boot and make sure it keeps running.

With everything in place, I can resize any image on my server, for example: // renders this image with a width of 1100px:


To finish everything off I found a LightRoom plugin that can publish photos through SSH. Now I can publish photos from LightRoom straight to my webserver and resize the photo in any way I want.