Starting Docker Daemon on Demand with Socket Activation

On my home computer, I use Docker from time to time. Since I don't need it
every day, I only start the daemon on demand though.

A pattern that occurs frequently is that I turn on my computer, try to start a
container I need, and then the following happens:

$ docker-compose up
ERROR: Couldn't connect to Docker daemon at http+docker://localunixsocket - is it running?
If it's at a non-standard location, specify the URL with the DOCKER_HOST environment variable.

Of course I could then manually start docker, re-run the docker-compose command,
and everything would work. But the people behind systemd had some better ideas
on how to solve the issue of network services that are only needed infrequently.

Socket Activation

Systemd implements a technique called socket activation. It basically means
that instead of starting a service that listens on a socket, a supervisor daemon
listens on behalf of those services. When a new connection comes in that wants
to talk to that socket, the service is started transparently in the background.
The connection is kept alive and handed over to the service as soon as the
service is up and running.

One of the downsides of this approach is that the service needs to be aware of
socket activation. Luckily support for systemd socket activation was implemented
in the Docker daemon in 2014.
(Unfortunately it's still missing
in PostgreSQL...)

Starting Docker on Demand

The first requirement for socket activation to work, is that the daemon is
started appropriately. For Docker, the daemon needs to be started with the -Hfd:// argument. This is being done correctly, as you can see in the service
file shipped with the docker package:

The second component that needs to be present is the socket unit
configuration. This is what the file looks like on Arch Linux:

# /usr/lib/systemd/system/docker.socket[Unit]Description=Docker Socket for the APIPartOf=docker.service[Socket]ListenStream=/var/run/docker.sockSocketMode=0660SocketUser=rootSocketGroup=docker[Install]WantedBy=sockets.target

To start Docker only on demand, we need to disable the service (to prevent it
for starting on boot) and to enable the socket.