Announcing Bildaro, a self-hosted photo gallery

It’s been a busy past couple of days! An idea I had over the weekend spawned a new little project that I’m eager to share.

I’m excited to announce Bildaro, a new self-hosted, minimalist, teeny tiny, mobile-friendly photo gallery and image processor/uploader.

Bildaro, a static site photo gallery written in Jekyll

Bildaro is a small-footprint Jekyll blog that, when combined with AWS S3 and AWS Amplify, provides a simple, performant, serverless way to self-host your photo collection at a very low cost.

You retain control over the platform and your content, and your site visitors get a fast, streamlined, simple experience.

The small codebase is easy to understand and welcomes tinkering so you can adjust it to your needs:

  • 30 lines of JS to power the image lightbox modal.
  • 260 lines of CSS (Sass) that Jekyll will compile for you on build.
  • 170 lines of code for the image processor and file uploader, written as a simple Bash script with no dependencies other than the tools it uses (imagemagick and aws cli via pip).
  • Other dependencies are minimal and are only needed if you want to run Jekyll locally (ruby and a few small Ruby gems).

And just to reiterate: The numbers above are not KB of code, they’re individual lines of code. Bildaro is smol.

Running your own web server requires expertise, takes considerable effort to get running, and requires an investment in long-term maintenance.

Many popular self-hosted solutions, like my previous all-time favorite Lychee, have grown into behemoths that require all sorts of dependencies just for a baseline install. And since they run on a live system exposed to the internet, they require vigilence to stay secure and operational.

A static website doesn’t require any maintenance, is practically immune to almost all of the typical vulnerability channels websites face because it doesn’t have any “moving parts,” and it can be served quickly and at massive scale for mere pennies.

The backstory

I’ve hosted a photo gallery in the past, but I was tired of maintaining it. I took it offline for a while to see if Dropbox would be sufficient. Turns out Dropbox is “just fine,” but it’s not an ideal experience. The web interface is heavy and bulky, full of log in dialogs, cookie notices, upsells, and now all this AI bullshit. It left me wanting to self-host again.

This past weekend I spun up a new web server to host Lychee, and it quickly became apparent that the project had just gotten really big for my rather basic needs. Composer, Laravel, Artisan, code linters, local development tools, CSS frameworks, Vue, Typescript, Font Awesome, gesture libraries… All in all about 400 MB of dependencies to download just to get started.

On top of that, don’t forget that you have the complexity of the baseline OS install to support the software stack in the first place. You’ll need Apache/nginx/lighttpd, PHP, and a database engine. Do you want MariaDB or SQLite? You have to keep all of these things updated. And backed up. Then there’s SSH, ZeroTier, Certbot and SSL certs and renewals, software dependencies…

That’s a lot of moving parts for something that feels so simple.

It got me thinking that there’s gotta be a better way.

My brain started turning:

  • My photo gallery website doesn’t change, except when I add or remove photos.
  • So if it rarely changes, why do I need a dynamically-generated, database-backed, full-blown web server running with dedicated CPU and RAM just to host a basic static site?
  • Could this be a static website in disguise? Should it have been one this entire time?

Jekyll to the rescue

Jekyll feels like an old friend. I’ve used the platform for years to create this blog, and other websites for business and hobbies. It’s a platform I know and trust. It’s focused, performant, and has powerful and useful features. And it took on absolute superpowers when served with AWS Amplify.

As soon as I realized the photo gallery site could be static, the flood happened. Everything fell into place.

  • The photo albums can just be posts, with YAML data storing all of the images in the album along with some basic metadata.
  • The images can live on AWS S3, where they can take up as much space as I need, and it’ll cost next-to-nothing. They can be decoupled from the blog, so I don’t have to worry about working with the images in the repo.
  • AWS Amplify can host the Jekyll site in a serverless fashion, like I do with this site. And it’ll be served from a CDN edge, with more performance than I could ever get out of the web server. (Frankly, more performance than I’ll ever need for my simple site.) And best of all, I won’t have to manage a single thing.
  • I can write a simple Bash script to convert the source JPGs into web-optimized webp thumbnails and the display size variants, create the album zip download file for people that want it, have it export an image manifest, and even upload all the files to S3 for me.
  • Changes happen as repo commits and can trigger build events, updating the gallery site.
  • The site can just fucking sit there and serve and serve and serve for pennies until I’m ready to change it. Like how this blog does. No moving parts. No worrying about software updates, Certbot renewal triggers, or anything that comes with running your own server. Ever.

So, I got to work!

Bonvenon, Bildaro!

I wrote Bildaro in the course of two days. Two good “sit down and focus” sessions is all it took. It all came together very quickly, because the premise is so simple: Bildaro is basically a Jekyll blog, nothing more.

Albums are simply posts, and they contain a YAML list of the photos in the album. The view page simply iterates over those images and creates the photo gallery output. The image URLs get prepended with the S3 bucket URL. And even better, this file is generated from the Bash script. All you need to do is edit the title and the cover image, commit the changes, and Amplify takes care of the rest.

Example album _posts/2023-09-17-satsop-nuclear-plant.md

---
title: Satsop Nuclear Plant
cover: DSC07949.jpg
download_size: 4264
pictures:
  - DSC07949.jpg
  - DSC08116.jpg
  - DSC08264.jpg
  - DSC08378.jpg
  - DSC08392.jpg
  - DSC08403.jpg
  - DSC08426.jpg
  - DSC08429.jpg
---

Since the page is static and written from scratch, it’s lightweight and performant. Check out these Pagespeed scores and see just how lightweight the gallery homepage is:

Tens across the board!

I’m sure there are other Jekyll photo galleries out there, but it felt so rewarding to write one for myself, from scratch. Tuned to do exactly what I need it to do, and nothing more.

“This is my gallery. There are many like it, but this one is mine.”

Bildaro is open source, released under the permissive MIT license. It’s given me great pleasure to write this little thing. You’re welcome to take it for a spin!

Or, just take a look at my photo gallery to see it in action.