Introduction
systemd is used in many mainstream Linux distributions like Arch Linux, CentOS, Debian/Ubuntu, RedHat/Fedora, openSuse, Slackware, CoreOS and more. It provides an easy way to manage and control services and a simple method of creating your own services. This will cover the process of creating and managing your own custom service.
You should copy your .service file to /etc/systemd/system
. Do not symlink it. One, you can't run systemctl enable because you it will not follow a symlink. Two, it potentially opens up a security risk (e.g. a shell). For example, you run your service as a low privilege user but you are symlinking the .service file. Someone finds a flaw in your service where they are able to overwrite or modify files. They can turn that in to code execution by modifying the .service file that your low privilege user has access to and changing the command that is run (ExecStart
). When the service is restarted the attackers command is run. This is also why you should not run the service as root.
Note that you can also put the files in /usr/lib/systemd/system/
but that should be reserved for system level packages. Anything in /etc/systemd/system
will override it and that is where user changes should go.
The .service file
Create a .service file in the systemd folder. For example /etc/systemd/system/my_daemon.service
. Here is an example .service file. If you want to create a user service that you can
run yourself without needing root permissions, you can put the service file
in $HOME/.config/systemd/user/my_daemon.service
.
[Unit]
Description=My Miscellaneous Service
After=network.target
[Service]
Type=simple
# Another Type: forking
User=nanodano # Omit user/group if creating user service file
Group=nanodano
WorkingDirectory=/home/nanodano
ExecStart=/home/nanodano/my_daemon --option=123
Restart=on-failure
# Other restart options: always, on-abort, etc
# The install section is needed to use
# `systemctl enable` to start on boot
# For a user service that you want to enable
# and start automatically, use `default.target`
# For system level services, use `multi-user.target`
[Install]
WantedBy=multi-user.target
There are more options you can specify. For example, in addition to ExecStart you can specify ExecStop and ExecReload to control what happens when stopping and restarting. Those are not required though. If you omit the ExecStop option, it is smart enough to know it should kill the process. If you need a more graceful shutdown though, specify that with ExecStop. To see some more options, look at man systemd.service in your distribution. Freedesktop.org's man systemd.service .
# Read all the service options
man systemd.service
Controlling the Service
If you are working with a user service, add --user
flag to all systemctl
commands.
# Control whether service loads on boot
sudo systemctl enable my_service
sudo systemctl disable my_service
# Manual start and stop
sudo systemctl start my_service
sudo systemctl stop my_service
# Restarting/reloading
sudo systemctl daemon-reload # Run if .service file has changed
systemctl --user daemon-reload # For user services
sudo systemctl restart my_restart
# Or if working with a user service add --user flag
systemctl --user restart my_user_service
View Status/Logs
These commands show how to use systemctl
to view the status of all services, specific services,
and user services. It also shows how to use journalctl
to review logs.
Note that if you want to use journalctl
as a low-privilege user to view
user service logs, the user needs to be in the systemd-journal
group.
# See if running, uptime, view latest logs
sudo systemctl status
sudo systemctl status my_service
# Or for a user service
systemctl --user status my_service
# See all systemd logs
sudo journalctl
# Tail logs
sudo journalctl -f
# Show logs for specific service
sudo journalctl -u my_daemon
# For user service
journalctl --user-unit my_user_daemon
Troubleshooting
- Make sure you have a FULL path for yor ExecStart, not a relative one.
- If you get an error like
Failed at step GROUP spawning /bin/sh: Operation not permitted
add aGroup=somegroup
explicitly in the service file OR omit User and Group completely. - If you can't read the journalctl as a user using user services, update the journald config:
sudo vi /etc/systemd/journald.conf
Old Config:
[Journal]
#Storage=auto
New Config
[Journal]
Storage=persistent
Then restart:
systemctl restart systemd-journald
Conclusion
After reading this, you should understand how to create simple systemd services for the system and as a low-privilege user. You should also know how to manage, view status, control, and view logs for services.