WordPress Powered by GitHub and Docker

About 5 years ago I migrated this blog to WordPress. Overall, it’s been working well but my manual method for keeping WordPress (and plugins/themes) updated has been less than ideal. I just implemented a new system with GitHub and Docker that will hopefully make that upgrade path smoother, help me keep things updated, and avoid security issues from out of date code.

Photo of a wall safe

Manually keeping WordPress up to date

This site has used a pretty typical WordPress installation on a shared web host and MySQL database both provided by Pair.com. About a year after migrating to WordPress, my site was hacked and I lost all Google traffic for over a week. I never sorted out how the hack happened, but my guess was it came in through a WordPress bug since I was running an out of date version.

After that experience I was paranoid to let WordPress write any files or auto-update itself, so I changed all the file permissions so that WordPress (Apache) would not have write access. That seemed to help, but the downside was it forced me to always follow the manual WordPress update instructions. All of these updates and other changes were all done on the live site, so it was kind of hard to experiment or make any big changes.

Goals for a better WordPress solution

The first foundational steps I needed were:

  • Make updates to WordPress (and plugins/themes) easier
  • Keep the PHP file tree secure (not directly writeable by WordPress)
  • Be able to test changes locally before pushing to production
  • Get on the latest version of everything

Once that foundation was in place, I could get back to real improvements such as:

  • Improving content, design, and social media connections
  • Switching to a different web host (possibly using Docker containers)
  • Improving performance scores
  • Switching to SSL

The new solution using WordPress with Docker

I decided to give Docker a try for the main purpose of being able to run a local instance of my blog, letting me test with local changes before pushing to the live site. I got everything working with a Docker image and the core of WordPress code, themes and plugins all stored in GitHub. Here’s the overall scheme:

System diagram of WordPress Docker solution

These are all the moving pieces:

  • A private GitHub repo contains the Docker config files, some helper scripts, and the full source tree for my WordPress plugins and themes
  • The WordPress uploads directory (images) stays only on my live host and is not committed in GitHub
  • The Docker Compose configuration brings up WordPress and MariaDB containers together
  • The WordPress container extends from the standard WordPress using a specific version tag (as of this writing: wordpress:5.2.4-php7.2-apache), but replacing the plugins and themes directories with my own
  • The MariaDB container is preloaded with a recent SQL backup of my live blog database (this ensures I’m running the same config including theme customizations; and has the added benefit of having recent blog posts running locally too)
  • To update the live site code tree, I save (copy out) the HTML tree from the local running WordPress container
  • All of the compose and related commands are managed in a Makefile to make life a bit easier

The relevant Docker configs (and my Makefile) are as follows:

(If the embed isn’t working, refer to this GitHub Gist.)

The workflow isn’t as smooth as I’d like yet, but it’s an improvement over the old manual steps. For example, to update the WordPress version the steps are:

  1. Edit the version (tag) for WordPress in Dockerfile
  2. Bring up the local environment (make clean; make data; make up)
  3. Test and confirm that everything is working as expected
  4. Export the HTML from the running container (make html)
  5. Rsync the HTML local tree up to the live site (make rsync)
  6. Git commit the local changes

A similar flow is done for making plugin updates or theme changes.

Sources and further reading

Photo by Gabriel Wasylko on Unsplash