A couple of months ago, what should have been a routine upgrade via the WordPress UI started alarm bells going off: fail2ban was complaining about the version of PHP I was using. My attempt to update PHP turned into a can of worms, because the version of Debian that I use on the vm for hosting was pretty old. I thought it would be an interesting learning exercise to build out a new vm for the upgrade using Docker [and Docker compose] for WordPress, MySQL, PostFix and Dovecote. ‘Interesting’ turned out to be ‘quite a lot of work’.
I didn’t use the stock WordPress container: there are a few customisations that I wanted to add, and which [at the time] seemed a bit tricky to shoehorn in.
The main thing I wanted to do was to get a certificate from LetsEncrypt on startup; I’ve created a cron which should request a replacement cert every month; I also have a pretty nasty script which scans the Apache log files for people trying to break in, and adds them to iptables [I was never convinced that fail2ban was working as intended]. That’s another cron job, which runs every half hour. I’ve also added in a few utilities for debug. Finally, I have some static content – a pretty large galleries directory – which lives outside WordPress, and which I need to copy across.
There is a very heavily starred container – docker-mailserver – which took care of Dovecote and PostFix; it’s fantastic. I’ve configured it to mount in the volume where the WordPress certificate lives. I’ve noticed that its fail2ban is configured in turbo-facist mode: I initially couldn’t understand why I couldn’t connect to the server from my laptop. fail2ban had immediately blocked our public IP when it hit the server with an old password from my phone.
One other gotcha was around port exposure. I obviously didn’t want to map the MySql port to the outside world, but I got stuck at the WordPress install page that asks for the database details. I finally figured out that I needed to refer to server by its container_name.
There is a balancing act in terms of what to bake into the container. My it’s-exploded-and-I-need-to-start-from-scratch approach is to build my WordPress docker image; deploy it using docker compose; then import a backup using the All-In-One plugin. I had a bit of a think over whether or not to bake that in as well in but decided against it. While I could wget it [the same way I do with WordPress itself], it would have to be a reference to a particular version rather than the latest.
So my WordPress container isn’t exactly a work of art: it’s pretty flabby, with all of the nonsense I [tell myself I] need. In some performance testing, I also noticed that WordPress returned its results considerably slower than the hand-rolled equivalent. It’s hardly surprising: this is running on OVH’s cheapest vm and, with 3 containers running it has a fair bit on its mind.
Anyway, if you actually know anything about Docker, you can amuse yourself with my efforts here.