Let's say you have a docker
application you want to always have running on your server (e.g. a home server, a DigitalOcean droplet, etc..)
You want this application to run as hands-off as possible, which means:
- You want it to start automatically when your server starts/restarts
- You want it to restart automatically if it ever crashes or the process is killed
On Linux we can do both of these easily with systemd
, a service manager that comes pre-installed with most Linux distributions.
The examples below refer to mealie, a recipe manager which comes packaged as a Docker image. However, these instructions can be adapted for any docker container you'd like to manage with systemd
.
Creating wrapper scripts
systemd
manages services by calling pre-defined commands that start
, stop
, and reload
a given service. So the first thing we'll do is define bash
wrapper scripts that systemd
can use to start
and stop
our docker container(s).
Notice how the "start" script safely creates containers only when one doesn't exist. Implementing custom logic like this is one of the advantages of wrapping our docker commands in a bash
script instead of providing systemd
with a direct docker start
or docker stop
command.
A few things to note:
- I'm choosing to store my wrapper scripts under
/var/mealie/bin
, but you can choose any directory. - It is good practice is to use long options (
--env
) instead of shorthand (-e
) for automated scripts. They are easier to read and understand, and these aren't commands you'll be typing out manually. - Your own
docker
command might look slightly different (e.g. different volumes, ports, etc..), but be sure to always specify a--name
. A fixed--name
makes it easier togrep
thedocker ps
list for your container. If you don't specify one, docker will generate a random name.
systemd
runs as root
, so ensure these scripts are owned by and accessible to root
:
chmod -R 700 /var/mealie/bin/
chown -R root /var/mealie/bin/
Creating the systemd
Unit File
systemd
uses configuration files (which it calls "unit files") to define services and their behavior. On many Linux installations these files are located at /etc/systemd/system/
(see this post on how to list all the directories systemd
uses).
Create a unit file /etc/systemd/system/{name}.service
for your new service, replacing {name}
with the name of your service.
systemd
provides many more configuration options. See the [Unit]
man page and [Service]
man page.
The above configuration file:
- Defines a service (in this case, one named
mealie
). - Defines dependent services (
docker
,containerd
) that must be started before this service starts. - Defines commands (our wrapper scripts) that can be used to
start
andstop
the service. - Tells
systemd
to start this service automatically on system boot (WantedBy=
) - Tells
systemd
to restart this service automatically if it stops for any reason (besides a user manually stopping it)
Set the permissions for this new file:
chmod -R 644 /etc/systemd/system/mealie.service
chown -R root /etc/systemd/system/mealie.service
Finally, enable
your new service. systemctl
is the command used to interface with systemd
services.
sudo systemctl enable mealie
Conclusion
And that's it! ✨
You can now easily start
, stop
, and reload
your service at any time using systemctl
:
sudo systemctl start mealie
sudo systemctl restart mealie
sudo systemctl stop mealie
start
your service and verify the status
is now "active (running)"
:
$ sudo systemctl status mealie
● mealie.service - Mealie recipe web application
Loaded: loaded (/etc/systemd/system/mealie.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2021-11-12 15:43:37 EST; 1 day 3h ago
Main PID: 1239 (bash)
Tasks: 10 (limit: 2147)
Memory: 73.5M
CGroup: /system.slice/mealie.service
├─1239 bash /var/mealie/bin/start
└─1379 docker start --attach mealie_v0.5.1
You can also verify your docker container is running using docker ps
(you may need to be root
):
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b9ea471c7153 hkotel/mealie:v0.5.1 "/bin/sh -c /app/mea…" 28 hours ago Up 27 hours 0.0.0.0:9925->80/tcp, :::9925->80/tcp mealie_v0.5.1