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 versionRecently, 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:
- Create a new branch in my repo
- Move the older trellis subfolder into a deprecated subfolder
- Clone in the latest trellis repository in its place
- Copy over the site configurations (mainly in the
- Spin up a new host using Ubuntu 20.04 LTS instead of my old Ubuntu 16.04 LTS instance
- Replace the old host with the new host IP address in
- Copy over my ssl certs from the old host to the new host
- Provision the new server
- Deploy the new server
- Dump the database from the old host and restore it on the new one
- Copy the media from the old
/srv/www/example.com/shared/uploadsto the same place on the new host
- Update my
/etc/hostsfile so I could browse the new site and check if anything had been broken
- Update my DNS settings on the domains to point the new host
- Enjoy the feeling of having your sites run on fresh hardwear!
Create a new branch with the latest Trellis versionMy 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 email@example.com:roots/trellis.git cd trellis rm -rf .git
Copy over my site settingsThe 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/productionfile 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 CertificatesIdeally, 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 filesThis 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 firstname.lastname@example.org:~/database_backup_thomas_carney_org.gz ~/dev/database_backups # rsync the backup to the new host rsync database_backup_thomas_carney_org.gz email@example.com:/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 firstname.lastname@example.org:/srv/www/thomascarney.org/shared/uploads ~/dev/uploads # Rsync the uploads to the new host rsync -rv uploads email@example.com:/srv/www/thomascarney.org/shared
Test the new host to see if everything is working correctlyIn order to do this, I update my
/etc/hostsfile 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 18.104.22.168 thomascarney.org