Top 6 changes in Docker CE 17.05

On May 5th 2017 the Docker engineering team released version v17.05.0-ce of the Docker CE product. The versioning is relatively new and follows a similar pattern to the Ubuntu project - YY.MM - so the next version will be 17.06 for June. CE stands for Community Edition and differentiates between this and the commercial offering.

Like most well-managed open-source projects a high-level changelog is provided with each release - this lets us know what new features are available and sometimes these link to Pull Requests to give additional context and discussion.

In this post I'll highlight a few of the changes.

Multi-stage builds

The long-awaited multi-stage builds were made available in the 17.05 CE release and also highlighted in the Dockercon keynote. This feature helps you separate your build-time dependencies from your runtime environment. In the case of a small Golang Dockerfile your resulting image could go from around 600MB in size to under 10MB.

--mount flag for docker run

The syntax for mounting volumes in docker run and Swarm is very different and that means learning two sets of syntax. The --mount change means docker run can now use the syntax from docker swarm create.

In this example I'll show the various options for mounting using the Portainer project which provides a free, feature-rich UI for Docker and Swarm.

Mounting a Docker volume with docker run

$ docker run -v /var/run/docker.sock:/var/run/docker.sock \
-p 9000:9000 -d portainer/portainer -H unix:///var/run/docker.sock

In Swarm you would have typed in:

docker service create \
--publish 9000:9000 \
--mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
portainer/portainer -H unix:///var/run/docker.sock

You can see the syntax is much more verbose and can be harder to remember. docker run can now use this same syntax:

docker run \
-p 9000:9000 \
--mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
-d portainer/portainer -H unix:///var/run/docker.sock

Dockerfile via stdin

A new change to the user experience means that you can now read a Dockerfile over stdin. I'm not sure this is a change everyone will need in their toolbox but advanced users may make use of it for scripting. It means that rather than reading a Dockerfile from disk - you can read it from the output of another program or the bash console.

Example:

$ docker build -t my-image . -f -

FROM alpine
RUN apk --no-cache add curl
CMD ["curl"]

(Control + D)

Did you know that the -f flag allows you to specify a different name or path for your Dockerfile? This can be useful when maintaining projects for different architectures. You could maintain a Dockerfile for Raspberry Pi called Dockerfile.armhf for instance and then build it on a RPi with docker build -t myimage:pi. -f Dockerfile.armhf.

Secrets get formatting

The CLI has improvements around inspecting and listing secrets created on your swarm.

For instance here is the regular output:

$ docker secret ls
ID                          NAME                        CREATED             UPDATED
180246v1yjayukr64ioxpgubw   func_accesskey              3 weeks ago         3 weeks ago
i1u0q0uhc7qxcmj6kr37kvv5a   func_secretkey              3 weeks ago         3 weeks ago

With a custom format you can pick whatever values you are interested in. The --format flag is already available for other commands like docker network inspect and docker inspect (for containers).

This gives us the id alone (useful for piping to xargs or scripts)

docker secret ls --format "{{.ID}}"

This gives the Name plus any Labels associated:

$ docker secret ls --format "{{.Name}}\t{{.Labels}}"
func_accesskey	com.docker.stack.namespace=func
func_secretkey	com.docker.stack.namespace=func

Setting up the daemon's data root

The --graph flag that can be configured on the Docker daemon to specify the root folder of your Docker library has had a name change. The flag is now called --data-root.

If you're using --graph or -G you don't need to change just yet but if you want to then find your systemd file with systemctl status docker. I'm on Ubuntu here so my file is at: /lib/systemd/system/docker.service.

So we can change the Docker data root from /var/lib/docker if we want to anything else by adding --data-root to our systemd file:

ExecStart=/usr/bin/dockerd -H fd:// --data-root=/mnt/ssd/lib/docker

Task logs for Docker Swarm

You can now fetch the logs for individual tasks or replicas for your Docker Swarm services. An example may be an NGinx webserver:

$ docker service create --name web --publish 80:80 --replicas=2 nginx

Your services will show up with two replicas or (tasks).

$ docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
sd86rprefd4c        web                 replicated          2/2                 nginx:latest        *:80->80/tcp

You can find the list of task ids from docker service ps web. The logs will be empty - so use curl to create some log entries, then review the logs.

$ curl http://localhost:80/page_a -4
$ curl http://localhost:80/page_b -4

Each replica will get one log entry.

$ docker service ps web
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE            ERROR               PORTS
1qzlqimfu5fi        web.1               nginx:latest        alexx               Running             Running 13 seconds ago                       
9oq9jz40vwfy        web.2               nginx:latest        alexx               Running             Running 13 seconds ago

Now checkout the logs of each individual task using the value from the ID column:

$ docker service logs 1qzlqimfu5fi
web.1.1qzlqimfu5fi@alexx    | 10.255.0.2 - - [15/Jun/2017:21:07:42 +0000] "GET /page_b HTTP/1.1" 404 169 "-" "curl/7.47.0" "-"

$ docker service logs 9oq9jz40vwfy
web.2.9oq9jz40vwfy@alexx    | 10.255.0.2 - - [15/Jun/2017:21:07:38 +0000] "GET /page_a HTTP/1.1" 404 169 "-" "curl/7.47.0" "-"

This will definitely be a handy feature for debugging services - especially when you need targeted logs.

Wrapping up

There's quite a few additional changes around the Docker Swarm CLI which you can read in the Changelog notes over on Github.

If you found this useful then checkout my archive of Docker and Swarm tutorials below:

Follow me on Twitter @alexellisuk

Share on Twitter