Systemd is increasingly popular way to manage process/executable on Linux. It provides lots of functionalities, including service/process, dependency, requirement, target management. Here are some resources to get started.
Important concepts
System, user unit files
standard system unit files: /lib/systemd/system
locally installed packages (e.g. via apt-get): /usr/lib/systemd/system
user/custom unit files: /etc/systemd/system
Type
simple: most common type,
forking: the binary will start another process
oneshot: the binary will do something then exit
notify: will send a notification when it has completed startup
Command
ExecStart: binary to run when you use systemctl start <service>
ExecStartPre: binary to run before ExecStart
ExecStop: binary to run when you use systemctl stop <service>
ExecStopPost: binary to run after ExecStop
Systemd target
Wantedby: The line WantedBy=multi-user.target in a service is essentially the same as specifying “this service should start in runlevels 3, 4 and 5” in SysVinit systems: it tells systemd that this service should be started as part of normal system start-up, whether or not a local GUI is active.
multi-user.target is usually the target on a server.
# get default end state of your system
systemctl get-default
Explicit ordering
Before=: the current unit needs to start before the specified dependency
After=: the current unit needs to start after the specified dependency
Podman
We can use systemd to manage container during system startup
— cidfile=file
Write the container ID to file.
— conmon-pidfile=file
Write the pid of the conmon process to a file. As conmon runs in a separate process than Podman, this is necessary when using systemd to restart Podman containers. (This option is not available with the remote Podman client)
https://www.freedesktop.org/software/systemd/man/systemd.unit.html
“%n” Full unit name
“%t” Runtime directory This is either /run (for the system manager) or the path “$XDG_RUNTIME_DIR” resolves to (for user managers).
In order to run systemd service running Podman as another user account without user explicitly logging in, you need to start user@.service (systemd user instance, which creates /run/user/<uid> folder). The systemd user instance is killed after the last session for the user is closed. The systemd user instance can be started at boot and kept running even after the user logs out by enabling lingering using
loginctl enable-linger <username>
and make sure your system service does not fail too fast, e.g. in your systemd unit file, adjust retry interval and number of retries
StartLimitInterval=60
StartLimitBurst=20
Podman API service
Podman 2.0 supports REST API. You can use that to do a lot of management tasks (like a single-machine Kubernetes).
And there is now a podman.socket systemd service to use systemd to manage lifecycle of Podman API
View log of systemd service
journalctl -u <service name>
Remove all exited containers
podman rm -f $(podman ps -a -f "status=exited" -q)
Other podman commands
Gotchas
There is something in systemd non-intuitive. Here are some I encountered:
- Cannot execute command and assign variable in systemd unit file, need to package in bash -c
- Cannot access environment variable, use defined specifier (e.g. %U for ${UID}) or execute a script and access in script