The default Docker config works but there are some additional features which improves the overall experience with Docker. We will create a JSON config file with optimized options for the Docker Daemon, install bash completion for the Docker CLI commands with one line and increase security. But first things first.

Docker / Docker Compose installation

Please refer to the official Docker installation docs to install Docker on your specific system. To install Docker Compose, you can simply execute the following command which downloads Docker Compose 1.11 and makes it executable. Make sure you are root, otherwise you get a permission denied error. Docker Compose simplifies Mult-Container apps. It is a tool for defining and running Multi-Container Docker applications and maintains a logical definition of a distributed application. You can then deploy this stack to your Docker Swarm Cluster with docker stack deploy --compose-file=docker-compose.yml my_stack. But this is another great story.

$ curl -L https://github.com/docker/compose/releases/download/1.24.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
$ chmod +x /usr/local/bin/docker-compose

Docker Daemon configuration

You can modify the Docker Daemon to improve overall performance and make it more robust. Especially the storage filesystem driver is a key component. We will use the overlay2 storage driver, which can be used with Linux kernel >= 4.0 and Docker >= 1.12. So make sure it is available on your system. There are some security features like user namespaces which should be enabled.

Let's activate our own configuration file by running this command.

Warning: Your current Docker configuration will be overwritten.

There is no way to move data from one storage to another, so all your Docker containers and images are not available anymore. You can delete everything before switching with the command docker system prune to save some disk space. This is optional of course and you may switch back, if you use your previous storage driver. Fasten your seatbelts and take off.

$ echo 'DOCKER_OPTS="--config-file=/etc/docker/daemon.json"' > /etc/default/docker

Create the file /etc/docker/daemon.json and put the following lines there. You find an excellent explanation of each configuration flag here. In short, we use the storage driver overlay2, enable JSON log files with logrotation and enable user namespaces. userns-remap uses UID and GID which is 1000 on my system. You can check these values for your user by executing the command id.

{
  "storage-driver": "overlay2",
  "graph": "/var/lib/docker",
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "2"
  },
  "debug": false,
  "userns-remap": "1000:1000"
} 

Docker CLI Bash completion

Do you know that Docker comes also with bash completion? This is really helpful. Make sure you are root, otherwise you get a permission denied error. The following command downloads the bash completion file for the current installed Docker version. You should also run this command after each Docker update.

curl -L https://raw.githubusercontent.com/docker/docker-ce/v$(docker -v | cut -d' ' -f3 | tr -d '\-ce,')/components/cli/contrib/completion/bash/docker > /etc/bash_completion.d/docker

The bash completion is also available for Docker Compose which makes things easier. The following command downloads the bash completion file for the current installed Docker Compose version. You should also run this command after each Docker Compose update.

curl -L https://raw.githubusercontent.com/docker/compose/$(docker-compose version --short)/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose

Now it's time to restart the Docker service with sudo service docker restart (Ubuntu) and with docker info you should get this info. The bash completion will be available if you reopen your terminal. Let me know if you have other Docker config improvements.

Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 0
Server Version: 1.13.1
Storage Driver: overlay2
 Backing Filesystem: extfs
 Supports d_type: true
 Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins: 
 Volume: local
 Network: bridge host macvlan null overlay
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 03e5862ec0d8d3b3f750e19fca3ee367e13c090e
runc version: 2f7393a47307a16f8cee44a37b262e8b81021e3e
init version: 949e6fa
Security Options:
 apparmor
 seccomp
  Profile: default
 userns
Kernel Version: 4.8.12-040812-generic
Operating System: Ubuntu 16.10
OSType: linux
Architecture: x86_64
CPUs: 8
Total Memory: 19.54 GiB
Name: [MACHINE NAME]
ID: [A LONG ID]
Docker Root Dir: /home/[YOUR USERNAME]/docker/100000.100000
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
WARNING: No swap limit support
Experimental: false
Insecure Registries:
 127.0.0.0/8
Live Restore Enabled: false

Conclusion

This blog post has shown how to configure and optimize the Docker Daemon configuration. The Docker Daemon has now more performance due the overlay2 storage and is more robust due the user namespaces. The CLI bash completion for Docker and Docker Compose is very handy too.