Systemd Service and Docker

Edit 25-10-2020

I've updated this post to show how to run docker-compose in Systemd as well

Some of my latest Kubernetes adventures have taken me into interesting corners of Linux. I have found myself writing several Systemd service files, which wasn’t near as horrible as I was expecting.

Below is a simple example for “MyDaemon”:

[Unit]
Description = "MyDaemon"
After=syslog.target network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/mydaemon
Restart=Always
Restart

[Install]
WantedBy=multi-user.target

To start the new service is also pretty simple:

systemctl daemon-reload
systemctl start

Docker

Docker, Docker, Docker. I find it quite rare these days that I am not running a service in Docker. When writing these Systemd service files, I had this odd feeling nagging at me. It dawned on me that I wasn’t just calling docker and pulling in the latest version, if I wanted these services to keep running I would have vend my own Debian and RPM packages.

So instead I just googled how to run containers as CoreOS does. Below is an example for running “MyDaemon” in Docker via Systemd

[Unit]
Description=MyDaemon Container
After=docker.service
Requires=docker.service

[Service]
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/docker stop %n
ExecStartPre=-/usr/bin/docker rm %n
ExecStartPre=/usr/bin/docker pull myusername/mydaemon
ExecStart=/usr/bin/docker run --rm --name %n myusername/mydaemon
ExecStop=/bin/docker stop %n
ExecReload=/bin/docker restart %n

[Install]
WantedBy=multi-user.target

This apparently has issues (although I haven’t experienced them), it is monitoring the client and not the container, so if the client disconnects from the container then the container will be restarted.

You might also want to check out systemd-docker I haven’t tried it but it is meant to help with several issues, with this setup.

Docker Compose

You can also do the same with Docker Compose so you can run serveral containers together to host a service.

[Unit]
Description=MyDaemon Compose
After=docker.service
Requires=docker.service

[Service]
Restart=always
WorkingDirectory=/etc/mydaemon
TimeoutStartSec=0
ExecStartPre=-/usr/local/bin/docker-compose down -v %n
ExecStartPre=-/usr/local/bin/docker-compose rm -v %n
ExecStart=/usr/local/bin/docker-compose up --remove-orphans
ExecStop=/usr/local/bin/docker-compose down -v %n
ExecReload=/usr/local/bin/docker-compose restart %n

[Install]
WantedBy=multi-user.target

I appreciate feedback so if you feel inclined to do so, reach out to me on twitter:

@neuralsandwich

References: