The best things about Docker (so far)

A new frontier for engineering has dominated every blog and conversation for months. Docker the container giant has arrived and if your team is not using it you’re like “so yesterday”.

We aren’t fans of those types of statements but we’ve recently started to explore what Docker can do for us. The recent introduction of Docker swarm mode really got us excited. We decided to port one of our less critical services to docker to see what all the fuss is about. These are some of our favourite things so far.

1. Dockerfiles

Dockerfiles are one of my favourite things about Docker. We’ve been using Saltstack at Old St Labs to manage our infrastructure. Over time it’s become a real P.I.T.A to manage.

When using tools like Salt I always felt it would be easier to write a bash script and deal with all the hate from my peers. Being able to open up a Dockerfile and add some bash commands via RUN statements is a great thing.

FROM python:3.5.2
WORKDIR /opt/code
ADD . /opt/code/
RUN python /opt/code/setup.py develop
EXPOSE 8080
CMD ["python", "example/app.py", "-p 8000"

The Dockerfile above provides us with a working container capable of serving requests from our python app. In 6 lines of code.

Dockerfiles == happy engineers.

2. Swarm Mode

Swarm mode was recently released as part of Docker 1.12. This release brought about the changes we had been waiting for. Orchestration of containers over many hosts, until swarm mode was introduced, was a challenge. There were a few options available like Consul and Kubernetes. I’ll admit we never gave any of those a shot as they all seemed complicated for our use cases.

Docker’s new command docker service is how the swarm and it’s containers are managed. The elegancy of it’s simplicity is just a joy to work with. It exposes all the similar APIs we’re used to when working with docker on a single host. Except now we can manage tasks running across many hosts using single commands.

Here’s an example of launching a new Nginx service into the swarm and then updating it to expose an extra port.

docker service create --name nginx --network front-tier 
--replicas 2 nginx:latest
docker service update --publish-add 80:80 nginx

Even rolling out a new version of Nginx is completely trivial.

docker service update --image nginx:1.11.3-apline nginx

Swarm mode comes with an internal DNS server that is capable of round robin lookups across hosts. It’s built on top of IPVS. This means a request on port 80 made to any node in the cluster will route seamlessly to any of the available Nginx containers in the swarm.

We can’t begin to describe how much this pattern of launching services has improved our existing dev operations.

Swarm mode == happy engineers.

3. Docker Compose

When I first encountered docker-compose it was a separate project called Fig. Fig, much like Docker at the time, felt a little unstable and lacked all the features I wanted. I’m pleased to say that’s no longer the case.

Docker compose is now an integral part of the Docker eco-system. Users are able to describe their services and the dependancies between them using a .docker-compose.yml file. It supports all the features Docker has to offer including the recently released swarm mode.

version: '2'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
depends_on:
- redis
redis:
image: redis

Running docker-compose up will build a container, pull any missing images and run the service. Being able to ship this around with your source code makes on-boarding new engineers to a project a piece of cake. We’re even using it to spin up the app for test runs on GitLab.

Being able to iterate quickly when writing software, I believe, is important. Adding a new version of Postgres or adding redis into the stack with docker-compose couldn’t be any simpler. We would have had 4 times the amount of code to have this working in salt.

Docker-compose == happy engineers.

4. Docker for OSX

I could put this as item 1,2,3,4 and 5! Docker for OSX shipped recently and has transformed the experience of using docker on a mac.

I had been using boot2docker for a while and had issues on and off. I think it was a great attempt to bring docker to OSX but it was pretty ambitious. The delicate balance of versions and networking required to use boot2docker was frustrating at best.

We are using Vagrant with a salt provisioner for our development environment. We have the local docker service talking to the Vagrant vm’s and vice versa with no problems. The simplicity of spinning up a clean dev environment is such that it prompted me to start new projects. That can’t be a bad thing (project pending of course)

Docker for OSX == happy engineers.

5. Immutable infrastructure

Last but not least is the concept of immutability. If you’ve read anything about Docker you’ll know that it’s greatest strength is immutability. The fact that you have the same container, running the same code anywhere is amazing.

We plan to take advantage of this to help us scale our QA and deployment processes. We hope to do away with siloed environments and have containers move all the way through testing to production. We hope to share more about that in the future.

Immutable Infrastructure == happy engineers.

Wrapping up.

We’re taking small steps with our move to Docker, migrating one service at a time. We’ve started with some of the more light weight services to ease the transition but so far we couldn’t be happier.

We’re always looking for ways to optimise all parts of system. From SQL performance tweaks to cutting down the time an engineer spends managing our infrastructure. Anywhere we can hand time back to our engineers to work on “the cool stuff” is always a no brainer for our team.

If you want to be a happier engineer and like the sound of what we’re up to, come join us, we’re hiring.