I’m a dinosaur who still believes that web feeds are a pretty neat idea. I wrote and maintain perlanet (a Perl program for aggregating web feeds into a new feed – and building a web site based on that new feed) and I use it to build a few sites on topics I’m interested in.
Last year, I worked out a way to use GitHub Actions to rebuild these sites automatically every few hours – thereby enabling me to host the sites on GitHub Pages (I still think it’s a useful technique, but I sometimes worry slightly about the large number of commits those repos have – someone at GitHub must surely notice one day!)
Yesterday, I was doing some light maintenance on one of those sites when I realised that each rebuild of these sites was taking a significant time (by which I mean four or five minutes) and started wondering if there was a way to speed them up and use less of GitHub’s resources. The problem is that Perlanet is a pretty hefty module and each rebuild was installing that module (and, therefore, dozens of other modules) on a pristine Ubuntu container.
When you say it like that, the solution is obvious.
You don’t need to run your GitHub Actions on the standard containers that GitHub supplies. You can run them on any container that’s available from any public container hosting service. So the solution was to build a Perlanet container and run the jobs using that instead. So that’s how I spent an hour or so yesterday.
Here’s the Dockerfile I ended up with:
RUN apt-get update && \
apt-get -y upgrade && \
apt-get install -y build-essential && \
apt-get install -y cpanminus libtidy-dev libxml++2.6-dev libhtml-tidy-perl && \
cpanm --notest Test::Exception && \
cpanm --notest Perlanet && \
cpanm --notest LWP::Protocol::https
It’s (obviously) available on GitHub in case anyone wants to improve on my rather ropey knowledge of Docker.
I explicitly install Test::Exception because HTML::Tidy (one of Perlanet’s pre-requisites) needs it and I can’t work out why the standard installation procedure isn’t installing it. And while, LWP::Protocol::https is, strictly speaking, not required by Perlanet, you wouldn’t get very far on the modern web if you only accessed web feeds that are available over HTTP.
A little bit of Docker Hub set-up and the container is available for everyone to use (and rebuilt automatically whenever I commit to the repo).
It was then just a case of changing my GitHub Actions to use my container. Here’s an example of one of the commits that did that.
I realise I’m pretty late to the party here, but I think this is a useful pattern. If you have a Perl library (or, indeed, any other software) that exists to provide a service to users then it’s a great idea to provide a containerised version of that software.
And I’m happy to report that my site rebuilds have gone from 4-5 minutes to about 45 seconds.
Also published on Medium.