Browse Source

add systemd service unit

This systemd service unit may serve as an example for package
maintainers to write their own units or can be used as-is to run
listmonk on a operating system that uses systemd as its init system.

This is a template unit so that multiple listmonk instances can be
started and controlled through the @-syntax. Instances are started by
calling `systemctl start listmonk@myinstance.service` which goes on to
read `/etc/default/listmonk` and `/etc/default/listmonk-myinstance` as
environment files, uses `/etc/listmonk/myinstance.toml` as the
configuration file and creates a state directory in
`/var/lib/private/listmonk-myinstance`.
Konrad Mohrfeldt 4 years ago
parent
commit
c10c03178b
1 changed files with 69 additions and 0 deletions
  1. 69 0
      listmonk@.service

+ 69 - 0
listmonk@.service

@@ -0,0 +1,69 @@
+[Unit]
+Description=listmonk mailing list and newsletter manager (%I)
+ConditionPathExists=/etc/listmonk/%i.toml
+Wants=network.target
+# The PostgreSQL database may not be on the same host but if it
+# is listmonk should wait for it to start up.
+After=postgresql.service
+
+[Service]
+Type=simple
+EnvironmentFile=-/etc/default/listmonk
+EnvironmentFile=-/etc/default/listmonk-%i
+ExecStartPre=/usr/bin/mkdir -p "${HOME}/uploads"
+ExecStartPre=/usr/bin/listmonk --config /etc/listmonk/%i.toml --upgrade --yes
+ExecStart=/usr/bin/listmonk --config /etc/listmonk/%i.toml $SYSTEMD_LISTMONK_ARGS
+Restart=on-failure
+
+# Create dynamic users for listmonk service instances
+# but create a state directory for uploads in /var/lib/private/%i.
+DynamicUser=True
+StateDirectory=listmonk-%i
+Environment=HOME=%S/listmonk-%i
+WorkingDirectory=%S/listmonk-%i
+
+# Use systemd’s ability to disable security-sensitive features
+# that listmonk does not explicitly need.
+# NoNewPrivileges should be enabled by DynamicUser=yes but systemd-analyze
+# still recommended to explicitly enable it.
+NoNewPrivileges=True
+# listmonk doesn’t need any capabilities as defined by the linux kernel
+# see: https://man7.org/linux/man-pages/man7/capabilities.7.html
+CapabilityBoundingSet=
+# listmonk only executes native code with no need for any other ABIs.
+SystemCallArchitectures=native
+# Only enable a reasonable set of system calls.
+# see: https://www.freedesktop.org/software/systemd/man/systemd.exec.html#SystemCallFilter=
+SystemCallFilter=@system-service
+SystemCallFilter=~@privileged @resources
+# ProtectSystem=strict, which is implied by DynamicUser=True, already disabled write calls
+# to the entire filesystem hierarchy, leaving only /dev/, /proc/, and /sys/ writable.
+# listmonk doesn’t need access to those so might as well disable them.
+PrivateDevices=True
+ProtectControlGroups=True
+ProtectKernelTunables=True
+# Make /home/, /root/, and /run/user/ inaccessible.
+ProtectHome=True
+# listmonk doesn’t handle any specific device nodes.
+DeviceAllow=False
+# listmonk doesn’t make use of linux namespaces.
+RestrictNamespaces=True
+# listmonk doesn’t need realtime scheduling.
+RestrictRealtime=True
+# Make sure files created by listmonk are only readable by itself and
+# others in the listmonk system group.
+UMask=0027
+# Disable memory mappings that are both writable and executable.
+MemoryDenyWriteExecute=True
+# listmonk doesn’t make use of linux personality switching.
+LockPersonality=True
+# listmonk only needs to support the IPv4 and IPv6 address families.
+RestrictAddressFamilies=AF_INET AF_INET6
+# listmonk doesn’t need to load any linux kernel modules.
+ProtectKernelModules=True
+# Create a sandboxed environment where the system users are mapped to a
+# service-specific linux kernel namespace.
+PrivateUsers=True
+
+[Install]
+WantedBy=multi-user.target