A couple of weeks ago, a customer asked me how to restart containers automatically after a reboot of the underlying host. In his context, it was not an insignificant question because some containers are concerned by SQL Server databases and he wanted to stay relaxed as long as possible even after a maintenance of the Linux host by sysadmins. The concerned (DEV) environment doesn’t include container orchestration like Swarm or Kubernetes.

blog 139 - 0 - banner

The interesting point is there are several ways to perform the job according to the context. Let’s say I was concerned by services outside Docker that are depend of the containerized database environment.

The first method is a purely sysadmin solution that includes systemd which is a Linux process manager that can be used to automatically restart services that fail with restarting policy values as no, on-success, on-failure, on-abnormal, on-watchdog, on-abort, or always. The latter fits well with my customer scenario.

Is there advantage to use this approach? Well, in my customer context some services outside docker are dependent of the SQL container and using systemd is a good way to control dependencies.

Below the service unit file used during my mission and I have to give credit to the SQL Server Customer Advisory team who published an example of this file included in their monitoring solution based on InfluxDB, Grafana and collectd. The template file includes unit specifiers that make it generic. I just had to change the name of the system unit file accordingly to which container I wanted to control.

[Unit]
Description=Docker Container %I
Requires=docker.service
After=docker.service

[Service]
TimeoutStartSec=0
Restart=always
ExecStart=/usr/bin/docker start -a %i
ExecStop=/usr/bin/docker stop -t 2 %i

[Install]
WantedBy=default.target

Let’s say I have one SQL Server container named sql. The next step will consist in copying the service template to /etc/systemd/system and changing the service name accordingly to the SQL container name. Thus, we may now benefit from the systemctl command capabilities

$ sudo cp ./service-template /etc/systemd/system/[email protected]
$ systemctl daemon-reload
$ sudo systemctl enable docker-container@sql

That’s it. I may get the status of my new service as following

$ sudo systemctl status docker-container@sql

blog 139 - 1 - systemctl status docker container

I can also stop and start my SQL docker container like this:

[clustadmin@docker3 ~]$ sudo systemctl stop docker-container@sql
[clustadmin@docker3 ~]$ docker ps -a
CONTAINER ID        IMAGE                                   COMMAND                  CREATED             STATUS                     PORTS               NAMES
9a8cad6f21f5        microsoft/mssql-server-linux:2017-CU7   "/opt/mssql/bin/sqls…"   About an hour ago   Exited (0) 7 seconds ago                       sql

[clustadmin@docker3 ~]$ sudo systemctl start docker-container@sql
[clustadmin@docker3 ~]$ docker ps
CONTAINER ID        IMAGE                                   COMMAND                  CREATED             STATUS              PORTS                    NAMES
9a8cad6f21f5        microsoft/mssql-server-linux:2017-CU7   "/opt/mssql/bin/sqls…"   About an hour ago   Up 5 seconds        0.0.0.0:1433->1433/tcp   sql

This method met my customer requirement but I found one drawback in a specific case when I stop my container from systemctl command and then I restart it by using docker start command. Thus the status is not reported correctly (Active = dead) and I have to run systemctl restart command against my container to go back to normal. I will probably update this post or to write another one after getting some information on this topic or just feel free to comments: I’m willing to hear about you!

The second method I also proposed to my customer for other SQL containers without any external dependencies was to rely on the Docker container restart policy capability. This is a powerful feature and very simple to implement with either docker run command or Dockerfile as follows:

docker run -e 'ACCEPT_EULA=Y' -e 'MSSQL_SA_PASSWORD=P@$w0rd1' -p 1433:1433 --restart=unless-stopped -d microsoft/mssql-server-linux:2017-CU7

Restart-policy values as Always and unless-stopped fit well with my customer scenario even if I prefer the latter option because it provides another level of control if you manually decide to stop the container for any reasons.

I will voluntary omit the third method that consist in installing systemd directly into the container because it is not recommended by Docker itself and not suitable with my customer case as well.

See you!

By David Barbarin