OK Phil, what did you do this time?

Me??! Nothing…

OK, so a friend runs a collection of websites, which she generates offline using WordPress and the excellent WP2Static plugin, allowing us to host the sites behind a CDN (Azure in case you’re curious), and without having to manage WP online. This is officially a 2-way win for cost and security.

To do this, I built her a container image using a variant of Lokl that I have added an Azure uploader into, and shrunk the image size as far as possible, including replacing MariaDB with SQLite. She thus runs n (currently 4) instances of this container on her own machine, and changes are automatically synced to the hosting service in real time.

Earlier today she was looking at the admin panel and noticed that WordPress had an upgrade available, with a nice attractive button… sometimes you forget that you aren’t looking after an online WP instance, so the old “always upgrade for security” reaction kicks in. Suddenly she’s looking at this:
Wordpress database needs upgrading screen
..and WordPress doesn’t work anymore. Oops.

Better call… Phil?

Because she’s a smart cookie, this is where she stopped poking and contacted me - correct!

Now it’s possible that we could complete the upgrade, but it provides no useful new features for her sites, and doing this previously (out of curiosity) broke a few bits inside Lokl and WP2Static that took a considerable amount of time to find and fix. Our preferred solution is therefore to revert the button click and downgrade WordPress (remember, this is all offline so there are no security issues with old WP code running!). So err, how does one do that?

What did the Upgrade button do?

Because she runs >1 instance of this container, we can take a look at the installed WP files and find out what changed on the affected instance: pretty much all the .php files in the WP installation folder are newer, there are new themes and a couple of plugins have appeared.

Luckily all the actual site content in wp-content/database and wp-content/uploads seems unaltered from the last set of edits made (a few days ago).

The downgrade process

Once we had determined that the database and media files were still intact then it was clear that we could pull the WP installation from another unaffected instance and unpack it on the broken one, tar to the rescue!

Here’s the specific workflow:

  • [host] Connect to the broken container: docker exec -it <broken> /bin/bash
  • [broken] Back up the site content: cd <wp install>; tar czf /tmp/content.tgz wp-content
  • [host] Connect to a donor instance: docker exec -it <donor> /bin/bash
  • [donor] Yank WordPress install: cd <wp install>; tar czf /tmp/wp.tgz .
  • [host] Transfer the donated install: docker cp <donor>:/tmp/wp.tgz - |docker cp - <broken>:/tmp/wp.tgz
  • [donor] Tidy up donor: rm /tmp/wp.tgz; exit
  • [broken] Stop WP (YMMV): ps |fgrep php; kill <php-fpm pid>
  • [broken] Nuke WP install: cd ..; rm -rf <wp install>
  • [broken] Unpack donated WP: mkdir <wp install>; cd <wp-install>; tar xvf /tmp/wp.tgz
  • [broken] Remove content: rm -rf wp-content/database wp-content/uploads
  • [broken] Unpack backed up content: mkdir restore; cd restore; tar xvf /tmp/content.tgz
  • [broken] Restore database: mv restore/wp-content/database wp-content
  • [broken] Restore media files: mv restore/wp-content/uploads wp-content
  • [broken] Tidy up broken: rm -rf restore /tmp/content.tgz /tmp/wp.tgz; exit
  • [host] Restart: docker stop <broken>; docker start <broken>

Now go check stuff is working :)

Sip tea in relaxed manner.