Patching php2shell in My Alpine Lighttpd PHP Docker Image
If you use my alpine-lighttpd-php Docker image, please pull :latest again and recreate your container. The image now runs PHP 8.4.27, which fixes the php2shell vulnerabilities.
docker pull alastairhm/alpine-lighttpd-php:latest
# or
docker pull ghcr.io/alastairhm/alpine-lighttpd-php:latestWhat is php2shell?
php2shell is the name for two PHP vulnerabilities, CVE-2026-109618 and CVE-2026-109619. Both are critical, and both allow remote code execution with no authentication. PHP published a security advisory on 21 October, alongside fixed releases 8.5.12, 8.4.27, 8.3.36 and 8.2.35.
New Posts Now Announce Themselves on Bluesky
New posts on this blog now get announced on Bluesky automatically, alongside the Mastodon toots that were already going out. If you’re reading this via a Bluesky link card, that’s the thing working.
It went live on 16 October, with the Inktober “Gangly” post being the first one through, and it’s been quietly doing its job since.
How it works
The whole thing is a GitHub Actions workflow plus a small Python script, with no third-party service in the middle.
Claude Has Made Posting Here Frictionless
Quick update rather than a full write-up: since pointing Claude Code at this blog’s repo a few weeks back, the whole loop of writing, publishing, and maintaining this site has stopped being a chore.
The biggest change isn’t any single fix — it’s that the friction just isn’t there any more. Drafting a post, sorting front matter, fixing up a GitHub Actions workflow that’s drifted out of date, branching and PR-ing a change, merging it once it’s built cleanly — all of that used to be enough faffing about that posts would sit as unfinished drafts for weeks. Now it’s a five-minute conversation and it’s live.
Generative Art with Context Free
I’ve got a small repo, ContextFree, that I keep coming back to whenever I want the specific kind of fun that comes from writing a handful of lines of code and having something unexpectedly pretty fall out the other end. It’s a collection of Context Free Art scripts — a tiny grammar for describing images as recursive drawing rules — plus a Docker image wrapping the cfdg renderer so I can run them without installing anything locally.
Two Weeks of GoatCounter Data
Back when I wired GoatCounter into this blog, the honest answer to “does any of this actually get read” was a shrug — no analytics meant no way to know. It’s been running for a couple of weeks now, so pulled the first export and had a proper look.
Rather than paste a wall of numbers, here’s the breakdown as an actual chart — daily pageviews, top pages, referrers, and where the hits are coming from:
Gemini Tests
Taking Antigravity for a spin
Been using Claude Code as my daily driver for a few days now, so when Google’s Antigravity CLI showed up I figured it was worth a proper look rather than just reading the launch blog post. Ran it side by side with Claude Code on the same kind of day-to-day work — repo exploration, small fixes, the usual — to see how the two actually compare in practice rather than on paper.
Blowing the Cobwebs Off This Blog with Claude Code
A Hugo repo hadn’t been looked at properly in a while
This blog is just Hugo content and a vendored theme — no app code, nothing exciting — which is exactly the kind of repo that quietly accumulates small rot nobody notices because nothing ever actually breaks the build. Spent a session pointing Claude Code at it to find and fix that rot.
Started with a straight status check: a couple of generated CSS cache files showing as deleted (build artifacts that shouldn’t have been tracked in the first place) and a stray uncommitted edit sitting inside the ananke theme submodule from as far back as November 2024. Both restored/reverted to get back to a clean tree before touching anything else.
Vibe Coding fractalPy with Claude
Vibe coding a Mandelbrot renderer
Spent today “vibe coding” with Claude, just describing what I wanted and letting it drive, to see how far that gets you on a small self-contained project. The result is fractalPy, a small Numba-accelerated Mandelbrot set renderer.

It started as a single script — render the set to a PNG, colour it, done — using @njit(parallel=True, fastmath=True, cache=True) to JIT-compile the escape-time kernel so it’s fast enough to iterate on interactively:
Cascading Updates
Having been a bit lazy in not updating my Hugo version since I started which was recently breaking one of my Github actions, I decided do do that.
This lead to an cascading update cycle.
- Updating Hugo version broke the theme I was using.
- Updating the theme broke the Tweet shortcode, no longer on Twitter so edited those post which referenced my old Twitter account.
- Updating the Hugo version, broke the Github Action which was building and uploaded to S3. This was due to newer versions of Hugo now having an “extended” and “with_deploy” versions.
- Raised a PR against the Github action to update to use the “with_deploy” version.
Still a couple of deprecated warning and fixing background and social icon links to sort out but at least now running against the latest version of Hugo.