Dispatches from the frontlines of the business of making software.

trellis from roots.io

Upgrading Trellis

I have a couple of websites that I host using WordPress. Hosting WordPress can be a frustrating experience with crappy shared hosts or super expensive options.

However, I’ve found that Trellis together with a few of the other projects (Bedrock and Sage most notably) from the roots.io project make it a much less painful endeavour. They also let you host a relatively high performance website on a cheap host. In my case, I host about three different WordPress sites on one $5/month Linode host. Trellis basically uses Ansible to provision a modern LEMP stack using Nginx, MariaDB, PHH 7.4 and Composer along with lots of other good stuff. You get good SSL support out of the box as well as micro-caching using Nginx FastCGI “micro” caching. Thrown in for free, you get a bunch of good practices for your WordPress box right out of the box in terms of security and performance.

I needed to upgrade my Trellis version

Recently, I had an embarrassing outage on my private blog: the SSL cert had expired. The reason was that my outdated version of Trellis was using an deprecated API from Letsencrypt. I managed to cherry-pick the changes from the latest Trellis release to get my site back online. However, it showed that dangers of not keeping your infrastructure code up-to-date. So, I set about upgrading my Trellis version. My basic approach was as follows:
  1. Create a new branch in my repo
  2. Move the older trellis subfolder into a deprecated subfolder
  3. Clone in the latest trellis repository in its place
  4. Copy over the site configurations (mainly in the group_vars folder).
  5. Spin up a new host using Ubuntu 20.04 LTS instead of my old Ubuntu 16.04 LTS instance
  6. Replace the old host with the new host IP address in trellis/hosts/production
  7. Copy over my ssl certs from the old host to the new host
  8. Provision the new server
  9. Deploy the new server
  10. Dump the database from the old host and restore it on the new one
  11. Copy the media from the old /srv/www/example.com/shared/uploads to the same place on the new host
  12. Update my /etc/hosts file so I could browse the new site and check if anything had been broken
  13. Update my DNS settings on the domains to point the new host
  14. Enjoy the feeling of having your sites run on fresh hardwear!

Create a new branch with the latest Trellis version

My setup is similar to the one outlined in the roots.io documentation. I have a repository that contains both the Bedrock wordpress site and a folder containing the Trellis repository. Therefore, my approach was to move the old trellis folder to a deprecated folder so I could still have access to all my settings. I then cloned the latest master branch of the Trellis repo and removed the git repo from it because I’ll commit the entire project to my repo.
cd ~/dev/my-wordpress-repo
mv trellis deprecated-trellis
git clone git@github.com:roots/trellis.git
cd trellis
rm -rf .git

Copy over my site settings

The group_vars folder contains the vault credentials as well as the setup parameters for the various sites you have in the repo. Therefore, I checked whether the format was still the same and then copied them over to the new trellis folder. The hosts/production file contains the IP address of your host. In my case, I updated it to my new host I’d just spun up on Linode in my case.

Copy over SSL Certificates

Ideally, I want a zero downtime upgrade, so my strategy is to deploy the sites on the upgraded server and then switch over the DNS to point to the new server once everything seems to work fine. However, generating a new SSL cert on the new server will fail, because the challenge part, where the Letsencrypt servers request a file on the new server for the domain will use the old server. One solution I found was in this GitHub issue for the Trellis CLI tool where you just copy over the SSL certs from the original server to a new one. Once you switch over your DNS to point to the new server, you can regenerate a cert using Letsencrypt on the new server.

Dump and Restore the Database and copy over the media files

This part could be automated in Ansible workbooks but for speed, I just did it manually (writing this out from memory).
# on the old host
cd /srv/www/thomascarney.org/current
wp db export - | gzip > database_backup_thomas_carney_org.gz

# rsync the backup to my local machine
rsync -a web@173.230.140.56:~/database_backup_thomas_carney_org.gz ~/dev/database_backups

# rsync the backup to the new host
rsync database_backup_thomas_carney_org.gz web@104.200.28.168:/home/web

# on the new host restore the database back into the database
gunzip -k ~/database_backup_thomas_carney_org.gz
mysql thomas_carney_production < database_backup_thomas_carney_org

# Rsync the uploads folder from the old host to my local machine
rsync -arv web@173.230.140.56:/srv/www/thomascarney.org/shared/uploads ~/dev/uploads

# Rsync the uploads to the new host
rsync -rv uploads web@104.200.28.168:/srv/www/thomascarney.org/shared

Test the new host to see if everything is working correctly

In order to do this, I update my /etc/hosts file to point to the new host. This way, I can browse the new host without having to switch over the DNS. This lets me catch any issues before rolling out the new host publically.
sudo vim /etc/hosts
# add the following to the file
104.200.28.168 thomascarney.org

Update my DNS settings to point to the new host

Now, I can finally update my dns settings on my domain host to point to the brand new shiny server.

Leave a reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: