Debian – How to properly handle a Docker container as a systemd service

debiandebian-stretchdockersystemd

I handle many services (databases, web servers…) implemented by docker containers via systemd units.
It works, but the system takes a very long time to shut down, apparently waiting for docker services to shut down.

Here is an example of a systemd unit I made in a virtual machine under Debian Stretch with Docker CE :

/lib/systemd/system/mariadb.service

[Unit]
Description=MariaDB
After=docker.service
Requires=docker.service

[Service]
TimeoutStartSec=0
Restart=always
ExecStart=/usr/bin/docker run --rm \
    --name=mariadb \
    -p 3306:3306 \
    -e MYSQL_ROOT_PASSWORD=root \
    -e MYSQL_DATABASE=test \
    -e MYSQL_USER=user \
    -e MYSQL_PASSWORD=user \
    -v /var/lib/mysql:/var/lib/mysql \
    mariadb:latest
ExecStop=-/usr/bin/docker stop mariadb # See UPDATEs 1 & 2

[Install]
WantedBy=multi-user.target

The service starts and stops properly in seconds when I use systemctl command. But when I shut the system down, it shows :

VM screenshot 1
VM screenshot 2
VM screenshot 3

It lasts more than 3 minutes. It can be longer if there are many containers running via systemd.

The problem is not specific to MariaDB.

Is there a better method to handle docker containers via systemd, avoiding extra shutdown time ?

  • UPDATE 1 : As Bennett Hardwick suggested in comment, I tried removing the ExecStop directive from the definition of the service. It seems better since the service stops after 1min 30 and not 3min.

  • UPDATE 2 : I tried to add the option -t to docker stop command in ExecStop directive (https://docs.docker.com/engine/reference/commandline/stop/). It has no effect.

Best Answer

A solution which is no longer maintained is systemd-docker, described as:

This is a wrapper for docker run so that you can sanely run Docker containers under systemd. The key thing that this wrapper does is move the container process from the cgroups setup by Docker to the service unit's cgroup. This handles a bunch of other quirks so please read through documentation to get an understanding of all the implications of running Docker under systemd.

Using this wrapper you can manage containers through systemctl or the docker CLI and everything should just stay in sync. Additionally you can leverage all the cgroup functionality of systemd and systemd-notify.

The problem of getting systemd-docker to work with recent Linux versions is discussed in the post Doesn't work with recent systemd and/or docker releases , where a user named james-cxx has reported success:

I was able to get systemd-docker working with Ubuntu 18.04 by:

My guess is that docker defaults to not using 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" (per the docker.service unit file), and I expect systemd-docker is expecting systemd for the cgroups, hence the open /sys/fs/cgroup/system.slice/docker.service/cgroup.procs: no such file or directory error. Setting --cgroups name=systemd apparently overrides the docker default, however, I cannot say what side-effects this may have, given the ominous note in the docker.service unit file.

An alternative to systemd-docker might be to use rkt, described as:

rkt is an application container engine developed for modern production cloud-native environments. It features a pod-native approach, a pluggable execution environment, and a well-defined surface area that makes it ideal for integration with other systems.

Related Question