How to start Docker service at system boot

This is just a reminder to always enable docker service at system boot.

Preliminary information

Operating system version.

$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 20.04 LTS
Release:	20.04
Codename:	focal

Installed docker package.

$ apt-cache policy docker.io
docker.io:
  Installed: 19.03.8-0ubuntu1.20.04
  Candidate: 19.03.8-0ubuntu1.20.04
  Version table:
 *** 19.03.8-0ubuntu1.20.04 500
        500 http://archive.ubuntu.com/ubuntu focal-updates/universe amd64 Packages
        100 /var/lib/dpkg/status
     19.03.8-0ubuntu1 500
        500 http://archive.ubuntu.com/ubuntu focal/universe amd64 Packages

Docker details.

$ docker version
Client:
 Version:           19.03.8
 API version:       1.40
 Go version:        go1.13.8
 Git commit:        afacb8b7f0
 Built:             Tue Jun 23 22:26:12 2020
 OS/Arch:           linux/amd64
 Experimental:      false

Server:
 Engine:
  Version:          19.03.8
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.13.8
  Git commit:       afacb8b7f0
  Built:            Thu Jun 18 08:26:54 2020
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.3.3-0ubuntu2
  GitCommit:        
 runc:
  Version:          spec: 1.0.1-dev
  GitCommit:        
 docker-init:
  Version:          0.18.0
  GitCommit:      

The problem

After system reboot docker service is stopped.

$ systemctl status docker
● docker.service - Docker Application Container Engine
     Loaded: loaded (/lib/systemd/system/docker.service; disabled; vendor preset: enabled)
     Active: inactive (dead)
TriggeredBy: ● docker.socket
       Docs: https://docs.docker.com

It will start after executing docker command-line utility.

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

This is because it is triggered by the docker socket.

$ systemctl status docker 
● docker.service - Docker Application Container Engine
     Loaded: loaded (/lib/systemd/system/docker.service; disabled; vendor preset: enabled)
     Active: active (running) since Sat 2020-07-18 11:10:13 UTC; 24s ago
TriggeredBy: ● docker.socket
       Docs: https://docs.docker.com
   Main PID: 265 (dockerd)
      Tasks: 21
     Memory: 102.3M
     CGroup: /system.slice/docker.service
             └─265 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

Jul 18 11:10:13 swarm-kraken dockerd[265]: time="2020-07-18T11:10:13.753469409Z" level=info msg="API listen on /run/docker.sock"
Jul 18 11:10:13 swarm-kraken systemd[1]: Started Docker Application Container Engine.

Inspect docker service file to see how it is triggered.

$ cat /lib/systemd/system/docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
BindsTo=containerd.service
After=network-online.target firewalld.service containerd.service
Wants=network-online.target
Requires=docker.socket

[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always

# Note that StartLimit* options were moved from "Service" to "Unit" in systemd 229.
# Both the old, and new location are accepted by systemd 229 and up, so using the old location
# to make them work for either version of systemd.
StartLimitBurst=3

# Note that StartLimitInterval was renamed to StartLimitIntervalSec in systemd 230.
# Both the old, and new name are accepted by systemd 230 and up, so using the old name to make
# this option work for either version of systemd.
StartLimitInterval=60s

# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity

# Comment TasksMax if your systemd version does not support it.
# Only systemd 226 and above support this option.
TasksMax=infinity

# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes

# kill only the docker process, not all processes in the cgroup
KillMode=process

[Install]
WantedBy=multi-user.target

Inspect docker socket file to see how it defined.

$ systemctl status docker.socket
● docker.socket - Docker Socket for the API
     Loaded: loaded (/lib/systemd/system/docker.socket; enabled; vendor preset: enabled)
     Active: active (running) since Sat 2020-07-18 11:06:51 UTC; 4min 33s ago
   Triggers: ● docker.service
     Listen: /run/docker.sock (Stream)
      Tasks: 0 (limit: 38388)
     Memory: 0B
     CGroup: /system.slice/docker.socket

Jul 18 11:06:51 swarm-kraken systemd[1]: Starting Docker Socket for the API.
Jul 18 11:06:51 swarm-kraken systemd[1]: Listening on Docker Socket for the API.
$ cat /lib/systemd/system/docker.socket
[Unit]
Description=Docker Socket for the API
PartOf=docker.service

[Socket]
ListenStream=/var/run/docker.sock
SocketMode=0660
SocketUser=root
SocketGroup=docker

[Install]
WantedBy=sockets.target

The solution

As you may have noticed, docker service is disabled by default.

$ systemctl is-enabled docker
disabled

Enable docker service and start it immediately.

$ sudo systemctl enable --now docker
Created symlink /etc/systemd/system/multi-user.target.wants/docker.service → /lib/systemd/system/docker.service.
$ sudo systemctl status  docker
● docker.service - Docker Application Container Engine
     Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
     Active: active (running) since Sat 2020-07-18 11:14:05 UTC; 15s ago
TriggeredBy: ● docker.socket
       Docs: https://docs.docker.com
   Main PID: 263 (dockerd)
      Tasks: 20
     Memory: 100.4M
     CGroup: /system.slice/docker.service
             └─263 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

Jul 18 11:14:05 swarm-kraken dockerd[263]: time="2020-07-18T11:14:05.713787002Z" level=info msg="API listen on /run/docker.sock"
Jul 18 11:14:05 swarm-kraken systemd[1]: Started Docker Application Container Engine.

Now, it will perform as expected.