How To Create And Manage Systemd Service Units
Systemd is the standard service manager on modern Fedora, RHEL, CentOS Stream, and many other Linux distributions. It starts processes during boot, supervises them while they run, records their output, and coordinates dependencies between services.
A systemd service unit is a plain-text configuration file that describes how a daemon or application should be launched. Learning to write these units gives administrators a consistent way to run Python applications, web servers, background workers, and custom scripts.
The commands in this guide work well on systems commonly used in Australian hosting environments, including Fedora servers in Sydney or Melbourne data centres. Use a test virtual machine first when changing production services, especially if the machine supports business websites or remote access.
The examples use a small application installed under /opt/example-app. Replace the paths, user names, and command lines with values suitable for your environment. Administrative commands require sudo or a root shell.
Understanding Unit Files And Service States
Custom service definitions normally belong in /etc/systemd/system/. Distribution-provided units are usually stored under /usr/lib/systemd/system/, and local administrators should avoid editing those files directly because package updates can overwrite them.
A basic unit contains sections such as [Unit], [Service], and [Install]:
[Unit]
Description=Example Background Worker
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=example
WorkingDirectory=/opt/example-app
ExecStart=/usr/bin/python3 /opt/example-app/worker.py
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
After= controls ordering, while Wants= requests that another unit is started. These directives do not automatically prove that a network connection is usable, so applications should still handle temporary network failures. The multi-user.target setting makes the service appropriate for a normal non-graphical server boot.
Creating A Dedicated Service Account
Running an application as root increases the impact of a compromised process. Create a system account with no interactive login, then give it ownership of only the files it needs:
sudo useradd --system --home /opt/example-app \
--shell /usr/sbin/nologin example
sudo chown -R example:example /opt/example-app
On some older distributions, the nologin path may be /sbin/nologin; check it with command -v nologin. Keep secrets outside application code, preferably in a root-owned environment file with restrictive permissions.
Create the unit with:
sudoedit /etc/systemd/system/example-worker.service
For a LAMP deployment, a comparable custom unit may manage a queue consumer or scheduled backend process alongside Apache, MariaDB, and PHP. A practical Fedora reference is this Fedora LAMP setup guide, which helps establish the surrounding platform before adding application services.
Loading And Starting The Unit
After saving a new or modified unit, ask systemd to reload its configuration:
sudo systemctl daemon-reload
sudo systemctl start example-worker.service
sudo systemctl status example-worker.service
start affects the current boot only. To launch the service automatically after future reboots, enable it separately:
sudo systemctl enable example-worker.service
Use enable --now when both actions are required:
sudo systemctl enable --now example-worker.service
A successful systemctl status result should show active (running), the main process ID, recent log messages, and the unit file location. If the service fails immediately, check the command path, permissions, working directory, and runtime dependencies before repeatedly restarting it.
Monitoring Logs And Diagnosing Failures
Systemd sends standard output and error output to the journal unless the unit specifies another logging method. View recent entries with:
sudo journalctl -u example-worker.service -n 50 --no-pager
sudo journalctl -u example-worker.service -f
The -f option follows new messages in real time, which is useful while testing a deployment. To inspect failures from the current boot, use journalctl -b -u example-worker.service. Australian operators supporting services across Brisbane, Perth, or Adelaide can also use journal forwarding or a central log platform rather than relying on one host.
When troubleshooting network-facing applications, confirm that the process listens on the expected address with ss -ltnp. Review firewall rules with firewalld, and avoid exposing administrative ports publicly. The same careful verification applies when assessing unfamiliar payment-related software, including a PayID casino guide: inspect what processes run, which users own them, and where connections are made.
Controlling Restarts And Service Limits
Restart=on-failure is a sensible default for daemons that should recover from crashes. Restart=always is more aggressive and can hide persistent configuration errors, while Restart=no leaves recovery to an administrator or an external monitoring system.
Add resource and startup controls when appropriate:
Restart=on-failure
RestartSec=10
StartLimitIntervalSec=60
StartLimitBurst=5
TimeoutStartSec=30
TimeoutStopSec=20
For security hardening, consider NoNewPrivileges=true, PrivateTmp=true, ProtectSystem=full, and ProtectHome=true. Test each option carefully because an application may need to write to specific directories or access particular devices. A restrictive unit that cannot start is less useful than a carefully scoped one that has been tested.
Managing Dependencies And Safe Changes
Use systemctl stop to halt a service, restart to stop and start it, and disable to remove it from automatic boot:
sudo systemctl restart example-worker
sudo systemctl stop example-worker
sudo systemctl disable example-worker
Before changing a unit, validate its syntax with:
sudo systemd-analyze verify /etc/systemd/system/example-worker.service
Then run sudo systemctl daemon-reload and check the status again. systemctl cat example-worker.service shows the effective unit file, while systemctl list-dependencies example-worker.service reveals related targets and services. Keep custom units in configuration management or version control so changes can be reviewed and reproduced.
A reliable service unit clearly defines its executable, user, working directory, restart behaviour, dependencies, and security boundaries. Remember to reload systemd after edits, enable only services that should start at boot, and use the journal as the first source of evidence when something goes wrong.