Keeping your Trellis Server Updated

When you manage client servers with Trellis you will every now and then have to update the server. This to keep Ubuntu, NGINX, MariaDB and PHP updated. But also to patch security holes and update the latest Linux libraries. So keeping your Trellis server updated is pretty important. And fortunately with Trellis it is all pretty straight forward.

Local Server Update

When there is a new update of the Ubuntu Bento Box you will see that when you start your Vagrant Box from the command line:

==> default: Removing hosts
==> default: Checking if box 'bento/ubuntu-16.04' is up to date...
==> default: A newer version of the box 'bento/ubuntu-16.04' is available! You currently
==> default: have version '2.2.9'. The latest is version '2.3.0'. Run
==> default: `vagrant box update` to update.

I really love that. No need to ssh into your box to do updates unless you want specific tweaks. Just keep up with the latest Bento Box updates and you should be just fine in the majority of the cases.

You can do a local update using the following command:

vagrant box update

This will then download the latest Bento Box from the Hashicorp Atlas Server and update your Vagrant Box. Bento is a great box based on an encapsulated Hashicorp Packer template for Vagrant Boxes maintained by the Chef team. The repo is here.

When all goes well you will see a message like:

==> default: Successfully added box 'bento/ubuntu-16.04' (v2.3.0) for 'virtualbox'!

If something did go wrong you will see a warning and or errors. Often this means you have to do it all again. From my location that will mean you will be spending another 20-30 minutes. So keep your fingers crossed at all times!

Remote Staging or Production Server Update

To update your live or production server or your staging server – if you use one – you will need to fire the following command:

ansible-playbook server.yml -e env=<environment>

This command is for provisioning a server, but also for updating the Trellis server. It is an Ansible playbook as Trellis is basically a set of playbooks to manage your server locally as well as remotely. To do this, this means you have to open the terminal, go to the trellis folder and type in

ansible-playbook server.yml -e env=production

NB server.yml can be viewed here

for example to update the production box. Do remember the remote site will not be accessible or fully accessible when you do this. So make sure you do this during slow traffic hours. Sometimes the update does not go well. Due to connection issues, issues with the Let’s Encrypt certificates or other issues. Run it again and all should work out well in the end. If things do go well you will see the following:

PLAY RECAP *********************************************************************

imagewize.nl               : ok=102  changed=6    unreachable=0    failed=0   

localhost                  : ok=0    changed=0    unreachable=0    failed=0   

So as you can see it all went well and six packages were changed:

TASK [fail2ban : ensure fail2ban is configured] ********************************
changed: [imagewize.nl] => (item=jail.local)
ok: [imagewize.nl] => (item=fail2ban.local)

TASK [ferm : ensure iptables INPUT rules are added] ****************************
ok: [imagewize.nl] => (item={u'dport': [u'http', u'https'], u'type': u'dport_accept', u'filename': u'nginx_accept'})
changed: [imagewize.nl] => (item={u'dport': [u'ssh'], u'type': u'dport_accept', u'saddr': [u'89.148.54.121']})
ok: [imagewize.nl] => (item={u'dport': [u'ssh'], u'seconds': 300, u'hits': 20, u'type': u'dport_limit'})

TASK [users : Setup users] *****************************************************
changed: [imagewize.nl] => (item={u'keys': [u'ssh-rsa 
key== user@imagewize.com', u'https://github.com/jasperf.keys'], u'name': u'web', u'groups': [u'www-data']})
changed: [imagewize.nl] => (item={u'keys': [u'ssh-rsa 
keyw== user@imagewize.com', u'https://github.com/jasperf.keys'], u'name': u'dhc-user', u'groups': [u'sudo']})

TASK [users : Add SSH keys] ****************************************************
changed: [imagewize.nl] => (item=({u'name': u'web', u'groups': [u'www-data']}, u'ssh-rsa A
key== user@imagewize.com'))
changed: [imagewize.nl] => (item=({u'name': u'web', u'groups': [u'www-data']}, u'https://github.com/jasperf.keys'))
changed: [imagewize.nl] => (item=({u'name': u'dhc-user', u'groups': [u'sudo']}, u'ssh-rsa 
key== user@imagewize.com'))
changed: [imagewize.nl] => (item=({u'name': u'dhc-user', u'groups': [u'sudo']}, u'https://github.com/jasperf.keys'))

TASK [mariadb : Add MariaDB MySQL deb and deb-src] *****************************
ok: [imagewize.nl] => (item=deb http://nyc2.mirrors.digitalocean.com/mariadb/repo/10.0/ubuntu trusty main)
ok: [imagewize.nl] => (item=deb-src http://nyc2.mirrors.digitalocean.com/mariadb/repo/10.0/ubuntu trusty main)
TASK [mariadb : Restart MariaDB MySQL Server] **********************************
changed: [imagewize.nl]

RUNNING HANDLER [fail2ban : restart fail2ban] **********************************
changed: [imagewize.nl]

In this case keys were changed, MariaDB upgraded and Fail2Ban configured anew.

Ansible Package Updates

Sometimes you do need quicker updates or just want to take care of other package updates. You may want to patch security holes or update packages you need the latest version for urgently. There is a Roots Discourse thread on updates where this is mentioned here. Swalkinshaw mentions here you can do three things for manual updates:

  • Add apt upgrade as a task for a server wide upgrade – did it before myself but do test locally or on staging first!
  • manually specify version for Ansible tasks being run for provisioning – see apt Ansible Books
  • or add latest=yes to any apt action

Real Guess has some scripts that I may implement in the future for Ubuntu updates here. It uses the mentioned Ansible apt module. But the examples Ansible mentions are also very useful.

Quick Security Updates

I do ran updates manually every now and then. And I sometimes do them on the server. To deal with security issues. Not as deterministic as I would like, but it does do the trick. I will incorporate some commands into tasks as soon as I can and write another blog post on it.

Earlier I had this shown on logging into one of my servers at Digital Ocean:

Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.4.0-34-generic x86_64)

* Documentation: https://help.ubuntu.com
 * Management: https://landscape.canonical.com
 * Support: https://ubuntu.com/advantage

System information as of Thu Oct 6 06:49:26 UTC 2016

System load: 0.09 Processes: 119
 Usage of /: 20.8% of 24.58GB Users logged in: 0
 Memory usage: 48% IP address for eth0: 208.113.134.123
 Swap usage: 1%

Graph this data and manage this system at:
 https://landscape.canonical.com/

Get cloud support with Ubuntu Advantage Cloud Guest:
 http://www.ubuntu.com/business/services/cloud

95 packages can be updated.
44 updates are security updates.

This was after a general provisioning. So to take care of the security packages I did a:

sudo unattended-upgrades -d
  • add the -d flag to get extra information

which works when the unattend-upgrades package is installed. It is on the Bento box. Running this package will update all unattended security packages – SO Thread. Sometimes including regular packages submitted by security maintainers or so it seems. And when I logged in again I saw:

59 packages can be updated.
6 updates are security updates.

Packages that were updated were:

dnsutils
libbind9-140
libdns-export162
libdns162
libisc-export160
libisc160
libisccc140
libisccfg140
liblwres141
libnss-myhostname
libpam-systemd
libssl1.0.0
libsystemd0
libudev1
linux-headers-generic
linux-headers-virtual
linux-headers-virtual-lts-xenial
linux-image-virtual
linux-libc-dev
linux-virtual
linux-virtual-lts-xenial
ntp
openssl
systemd
systemd-sysv
udev

So quite a few security packages were updated including SSL. New ones popped up and those can be dealt with the same way. This way is also pretty safe and clean. Better to build it into your Trellis workflow of course. I am working on another task for that. However, all in all a good solution to deal with security on your server in a semi automated and clean way. There are ways to run this in the background too, but so far I have preferred to do it this way, especially with the -d flag to keep everything under control.

So there you have it – keeping your Trellis server updated in a nutshell. You got feedback or questions? Leave a comment below and feel free to retweet or post to Facebook.

PS WordPress Core, plugins and theme updates are handled with

./deploy.sh production site.domain

following composer update. Another blog post on that later on.

Tagged in : Tagged in : , ,
Jasper Frumau

Jasper has been working with web frameworks and applications such as Laravel, Magento and his favorite CMS WordPress including Roots Trellis and Sage for more than a decade. He helps customers with web design and online marketing. Services provided are web design, ecommerce, SEO, content marketing. When Jasper is not coding, marketing a website, reading about the web or dreaming the internet of things he plays with his son, travels or run a few blocks.