Todo Lists Are Evil; You Should Definitely Use Them

Todo lists are great! You write down everything you need to do, split it into sub sections / sub-tasks, make it look pretty, and gain a massive sense of achievement.

Look at how productive I’ve been! I’m so organised!

Except all that you have really achieved is putting some stuff in a list.

But You Should Really Use Them

Having said all that, I’m still a big fan of having an up to date todo list:

A Starting Point for the day

Assuming your todo list is up to date, it acts as a great reminder of ‘where was I?’. This makes it much faster to get back into the flow of things.

Categorise Priorities

The modern workplace is a constant battle against interruptions: email, instant messaging, desk drive-bys; they are all source of more work to do, so it’s important to categorise what’s important, rather than just jumping to the most recent request.

Keeping a categorised list (I use ‘now’, ‘next’ and ‘future’) means new requests can be slotted in as appropriate, thus maintaining some semblance of flow.

Know what’s next

I find a key part of remaining productive is lowering the barrier to getting started on something. Having the decision made by a well defined list of ‘what’s next’ keeps thinking to a minimum.

Review what’s been achieved

Motivation ebs and flows. A great motivator is being able to review just how much has been achieved (assuming that is you’ve managed to get something done).

Taking a moment to review both the breadth of achievement, as well as key milestones is a great way to remind yourself that you’re on the right track.

Just Do It

So yes, Todo lists can be evil as a source of false sense of achievement, but as an organisational tool I find them to be one of the easiest ways to improve my own productivity.

You don’t need any fancy tools to get started, just open notepad++ and start writing stuff down!

Vagrant Life Cycle

Vagrant is a command line tool for building and managing virtual machine environments with a focus on automation through flexible configuration.

These are just some notes on how to get up and running, and working with the Vagrant life-cycle.

Starting Out

Having installed Vagrant and Virtual Box (On Ubuntu: ‘apt install vagrant virtualbox’), the first thing required is a Vagrantfile.

This file defines the required end state of your virtual envinronment. Here is a simple example:

Vagrant.configure("2") do |config| = "centos/7"
  config.vm.hostname = "vm2" "public_network"
  config.vm.provider "virtualbox" do |vb|
    vb.memory = "2048"
    vb.cpus = 2

‘’ defines the image you wish to create a VM from. Many community provided images are available at This example uses a CentOS image.

Create a directory and save the above as ‘Vagrantfile’. Inside that directory, running ‘vagrant up’ will retrieve the named image, create and configure an instance as specified:

rich@thevmserver:~/vagrant$ vagrant up
Bringing machine 'vm1' up with 'virtualbox' provider...
==> vm1: Importing base box 'centos/7'...
==> vm1: Checking if box 'centos/7' is up to date...
==> vm1: Running 'pre-boot' VM customizations...
==> vm1: Booting VM...
==> vm1: Waiting for machine to boot. This may take a few minutes...
<-- snipped some lines for brevity -->
==> vm1: Machine booted and ready!
==> vm1: Setting hostname...
==> vm1: Configuring and enabling network interfaces...
vm1: SSH address:
vm1: SSH username: vagrant
vm1: SSH auth method: private key
==> vm1: Rsyncing folder: /home/rich/vagrant/ => /vagrant
==> vm1: Running provisioner: file...

At this point, a fully functional VM is up and running, which can be accessed using ‘vagrant ssh’ (or externally via SSH if a public network was configured):

rich@thevmserver:~/vagrant$ vagrant ssh vm1
[vagrant@vm1 ~]$ hostname

Life Cycle

Some of the more useful life-cycle commands:

  1. up: creates VM instances as defined in config, and starts them
  2. halt: stops VM instances
  3. destroy: stops and deletes VM instances

Multiple VMs

Vagrant is also capable of managing multiple VMs in a single config. To do this use ‘config.vm.define’ for each instance:

Vagrant.configure("2") do |config|

  config.vm.define "vm1" do |vm1| = "centos/7"
    vm1.vm.hostname = "vm1"

  config.vm.define "vm2" do |vm2| = "centos/7"
    vm2.vm.hostname = "vm2"
  end "public_network"
  config.vm.provider "virtualbox" do |vb|
    vb.memory = "2048"
    vb.cpus = 2

Note that any config in the outer scope (e.g. is applied to all VM instances.


By default Vagrant will generate an SSH key for each VM, and use that to replace the insecure key most images are built with. To use a pre-defined key generated through ssh-keygen, update the vagrant file with:

config.ssh.insert_key = false
config.ssh.private_key_path = ["~/.ssh/id_rsa", "~/.vagrant.d/insecure_private_key"]
config.vm.provision "file", source: "~/.ssh/", destination: "~/.ssh/authorized_keys"

Change ~/.ssh/id_rsa and ~/.ssh/ to point at where your keys live.

Docker Container Upgrades on Synology

Synology provide great hardware for home storage, and moving up a tier from their budget offering adds a great deal of functionality, including full Docker support.

Inevitably Docker images will require updating; these are some quick notes on how to do that.

Docker Data Storage

Generally speaking, storing state within a docker container is discouraged. As the container could go away at any point, persistant data should be stored outside of it to separate the application from its state.

Docker provides various storage drivers to handle different workloads, each with different performance characteristics.

On Synology systems, Docker uses the Overlay volume to map container directories onto the host device’s file system.

Upgrade Process

This makes the upgrade process very straight forward, simply fire up the Synology Docker application, then:

  1. Goto ‘Registry’, search for the Image you wish to upgrade, and download (this will overwrite the existing version)
  2. Goto ‘Container’, and stop  the container you want to upgrade
  3. Clear the Container
  4. Start Container back up

That’s it, the container should now be on the latest version of the image, with all its previous state persisted.

Agile Teams and Stability

An agile team should be made up of committed individuals whose focus is solely with the team.

This is well understood to be a core tenet of taking an agile approach to software development (though this also applies regardless of development methodology).

Why is it Important?

Tuckman’s stages of group development, proposed back in 1965, suggests that new teams go through 4 stages: Forming, storming, norming and performing.

Forming, Storming, Norming, Performing

This model describes how a team takes time to truly gel, going through the stages of initially getting to know each other, gaining each others trust, resolving any personality clashes through the pursuit of a common goal, and finally ending with the motivation and knowledge to perform at a high level.

Changing the makeup of the team with even a single person can throw out the dynamic of the entire team, resetting this process back to ‘forming’. It’s important that a team is given the time to properly coalesce and enter the ‘performing’ stage.

The Impact of Change

When resetting the group dynamics, expect to see impact in some of the following ways:

  • Ownership: when a team has a sense of ownership of their work, they will be more engaged and committed to achieving great things. Who is responsible if people are coming and going?
  • Trust: this takes time to build. Once a team trusts each other is doing the right thing, they will often go the extra mile for each other.
  • Motivation: it can be a real motivation killer when conditions are changing constantly. “Why is bob moving to project Y, we had just formed a good working partnership?”

So Never Change?

That’s not to say that change should never be permitted.

Change will happen (it’s the only certainty in life after all), but it must be entered into with the understanding that it will have a sizeable impact on performance, and potentially start down a road towards more upheaval.

Why I Blog

Somewhat related to a previous post on procrastination, a few whys behind this blog…

If You Can’t Explain it, You Don’t Understand it

Often misquoted to Einstein, it appears the likely origin of this notion is Lord Rutherford of Nelson:

An alleged scientific discovery has no merit unless it can be explained to a barmaid.

Regardless, I find that writing about a subject forces a certain level of understanding, and helps organise my thoughts.

Building a Skill

Writing is a specific skill, which like most skills takes practice to improve.

Generating blog content provides a challenge in how best to present content, and hopefully generates growth in both how to think through a subject, and present the resulting information.

Continuous Learning

Aside from writing as a specific skill, working in the tech industry provides a lot of scope for new technologies to keep on top of.

Blogging as a learning mechanism is useful in of itself, both by forcing a level of understanding, but also as another reason to dig into a particular bit of technology. Content doesn’t have to be unique to be useful!

Shared Experience

If nothing else, I hope that others may find some of what I write useful, whether that’s from technical content or otherwise.

On Procrastination

Writing about procrastination seems like a good a way as any to pick up after a 7 year gap.

A lecture from Dr. Tim Pychyl was posted to Reddit recently, in which he discusses procrastination, its causes, and some strategies for change.

The lecture highlights some of the ways in which we deceive ourselves, mechanisms we use to give our brains those little dopamine hits to feel good now (writing to-do lists, distracting ourselves with something unrelated), whilst avoiding what we should really be doing (finishing that blog post).

Dealing with Procrastination

The main take away from the lecture for me was a very straight forward mechanism for dealing with it:

In situation X, I will do behaviour Y, to achieve subgoal Z.

By defining a task in terms a of a concrete start time, a well defined achievable task, and a reminder of why you are doing it in the first place, you remove a lot of the thinking involved in getting started in the first place.

Simply: The When, the What and the Why.


I like that this isn’t a million miles away from what we try to achieve as good agile practitioners; planning work as a series of small, well defined increments:

As a <person in a situation>
I want <a defined behaviour>
So that <sub-goal is achieved>

This is also not a million miles away from defining acceptance criteria in the Given / When / Then format.

Original Video