Adventures of a Technomancer

Adventures in WordPress Vol. 4 - Hardware and Software

With the foundation (or 'Bedrock') of this upgrade complete it's time to see what some upgrades will do.

The plan of attack is to change MySQL to MariaDB, upgrade PHP from 5.6 to 7.0 and upgrade the DO Droplet to something with more power.

MySQL -> MariaDB

Why MariaDB?

For a few reasons, mostly for the features and to support OSS. There are some speed enhancements if the benchmarks are to be believed.

Like before, I'm backing up all databases before I change anything. Just in case.

$ mysqldump --all-databases -u root -p | bzip2 -c > /root/backups/all-$(date +%Y-%m-%d-%H.%M.%S).sql.bz2
$ apt-get remove --purge mysql-server mysql-client mysql-common
$ apt-get autoremove
$ apt-get autoclean
$ apt-get install mariadb-server

PHP 5.x -> PHP 7

$ add-apt-repository ppa:ondrej/php
$ apt-get update
$ apt-get install php7.0 php7.0-mysql php7.0-mbstring php7.0-curl php7.0-gd php7.0-intl php7.0-xml php7.0-zip php7.0-fpm
$ php -v
$ a2dismod php5
$ a2enmod proxy_fcgi setenvif
$ a2enconf php7.0-fpm
$ service apache2 restart

Why PHP7?

This one's easy.

Twice the speed. Zoom zoom baby!

Resizing the droplet

Originally Bitten by the Travel bug was hosted on a simple 512MB RAM Digital Ocean droplet and was able to deal with the 40k hits per month.

Once the site started getting even popular (upwards of 100k hits per month) that original 512MB of RAM was not enough, so we picked the 2GB droplet and decided to monitor resource usage over 3 - 4 months and see if the smaller droplets would suffice.

Thanks to DO's Flexible Resize feature this can be done with minimal downtime.

Adventures in WordPress Vol. 3 - Converting WordPress to Bedrock

Bedrock is a modern WordPress stack that gets you started with the best development tools, practices, and project structure.

This post will be a little light on descriptions as it's fairly straightforward to move an existing WordPress project into a Bedrock stack. It's mostly moving directories around.

Backup the existing database

Always a good idea before messing with the database and performing a lot of updates.

$ mysqldump [database] -u [user] -p | bzip2 -c > [database]-$(date +%Y-%m-%d-%H.%M.%S).sql.bz2

Update the database

Replace all instances of wp-content with app

> UPDATE `wp_posts` set `guid` = replace(`guid`,'wp-content/uploads/','app/uploads/');

And again for post_content:

> UPDATE `wp_posts` set `post_content` = replace(`post_content`,'wp-content/uploads/','app/uploads/');

Moving plugins to composer.json

    "wpackagist-plugin/wp-instagram-widget": "^1.9",
    "wpackagist-plugin/akismet": "^3.1",
    "wpackagist-plugin/amazon-link-engine": "^1.2",
    "wpackagist-plugin/google-analytics-for-wordpress": "^5.5",
    "wpackagist-plugin/jetpack": "^4.0",
    "wpackagist-plugin/w3-total-cache": "",
    "wpackagist-plugin/wordpress-seo": "^3.3",



$ cp -r ./wp-content/themes/[theme name] [bedrock]/web/wp/wp-content/themes

And just like that we're now running a Bedrock based wordpress installation.

CDPATH with zsh

Here's some awesome knowledge passed along from @bradleyfalzon.

If you add CDPATH to ~/.zshrc you can tab complete into those directories without typing the full path.

Very handy if you happen to run several vagrant instances or a verbose directory structure to mimic production.

typeset -U path cdpath fpath

setopt auto_cd  
cdpath=($HOME/scripts /mnt)

zstyle ':completion:*' group-name ''  
zstyle ':completion:*:descriptions' format %d  
zstyle ':completion:*:descriptions' format %B%d%b  
zstyle ':completion:*:complete:(cd|pushd):*' tag-order \  
        'local-directories named-directories'

When tab completing a cd you'll end up with something like this;

The same can be done is bash by adding the following to your ~/.bashrc.

export CDPATH=.:$HOME/scripts:/mnt  

Adventures in WordPress Vol. 2 - Analysis & Clean up

Nicole of Bitten By the Travel Bug has reported some issues with her WordPress install but is unsure as to what is breaking. The only message she sees is;

Error establishing a database connection

So into the terminal I dive, ssh-ing into the server it's time to probe logs and run diagnostics.

This takes a while as I soon find out from htop that 100% CPU being used up by Apache, all RAM and swap is being used too. How is this server even functioning at this point?


Got to stop Apache from taking over

/etc/init.d/apache2 stop

Once that's done I check out /var/log/error.log for any recurring themes. I find mostly timeouts, a few mysql database connection errors and horribly coded WordPress plugins breaking. Those will be the first to go when the purge comes along.

Just to be careful, I run last and cat /var/log/auth.log | grep "invalid user" | wc -l to see if there has been anyone logging in. (Only 1302 attempts today, not bad)

Since this is a small Digital Ocean droplet I'm going to aggressively limit Apache to allow the site to function but not overload the server.

<IfModule mpm_prefork_module>  
        StartServers              1
        MinSpareServers           2
        MaxSpareServers           5
        MaxRequestWorkers         50
        MaxConnectionsPerChild    1000

And install fail2ban even though the only enabled method of ssh authentication is keys.

apt-get install fail2ban  


WordPress is known for being extensible via plugins, unfortunately these plugins had no peer review or standards to be held to. I have found many plugins which use file_get_contents on a long expired domain for whatever reason, leading to an extra 30 seconds of load time.

Plugins can cause trouble, but not all of them are bad. tail-ing error logs to find troublesome plugins makes it easy to identify some, while others need to be disabled through trial and error.

Originally Bitten By the Travel Bug had 33 active plugins, I was able to bring it down to 20, at least 5 of which I believe should not be plugins and should be part of the theme, but that's a job for another day.


Uploading 5mb images and letting WordPress create thumbnails is a good idea in theory, but the WP core doesn't optimise the files for slow connections.

Here is where jpegoptim saves the day. Optimising jpeg files through the command line saves hard drive space and gives the end user less to download for an imperceptibale loss of quality.

1 command and the uploads directory has been reduced by over half. And more can be saved by tweaking the output quality.

$ cd /wp-content/uploads/
$ du -s
754492  .

$ find . -regextype sed -regex ".*/*.jp[e]\?g$" -exec jpegoptim --all-progressive -o -m90 --strip-all {} \;

$ du -s
361112  .  

Adventures in WordPress Vol. 1 - An Introduction

A good friend of mine, Nicole, runs a travel blog called Bitten By the Travel Bug recently came to me with some WordPress troubles. Her WordPress install that deals with just under half a million hits per month is having a bit of trouble keeping up with the demand.

In this series I'll be investigating and documenting my findings, mistakes and fixes in the hopes that future developers - and maybe even future me - will find the information useful even if it only points them in the right direction.