Introduction
Systemd service units are files which define a service, and when/how it’s started. They will normally refer to a program or script to be executed. There are 3 fundamental sections on a service file:
[Unit]is where the description resides, as well as the conditions to initialize the service, such as requirements and dependencies.[Service]is where the parameters which determine how to run the service reside.[Install]is how to enable the unit. It’s optional, but normally necessary.
The [Unit] Section
Let’s go through some fundamental fields and what goes in them:
Description=A human-readable description. Example:Description=Apache Web Server.After=It determines after which units this unit will be started. Example:After=network.target.Before=It determines before which units this unit will be started. Example:Before=httpd.service.Requires=It determines a hard dependency, without which this unit fails. Example:Requires=network.target.Wants=This is a soft dependency. It should be started before this unit, but not required. Example:Wants=network-online.target.BindsTo=This is a stronger dependency thanRequires=. Stops if this dependency stops. Example:BindsTo=dev-sda1.device.
To summarize, there are fields which determine ordering: After= & Before=, and there are fields which determine dependency: Requires=, Wants= & BindsTo=.
The [Service] Section
These are the most usual fields which determine how the service:
Type=How Systemd tracks the service. Example:Type=simple.ExecStart=Command used to start the service. Example:ExecStart=/usr/sbin/httpd - DFOREGROUNDExecStop=Command to stop. This is optional,SIGTERMis default. Example:ExecStop=/usr/sbin/httpd -k stop.ExecReload=Command to reload configuration. Example:ExecReload=/bin/kill -HUP $MAINPIDRestart=When to auto-restart. Example:Restart=on-failureRestartSec=Delay before attempting to restart. Example:RestartSec=5User=Run this service as this user. Example:User=apacheGroup=Run this service as this user. Example:Group=apacheWorkingDirectory=Sets the working directory for the service. Example:WorkingDirectory=/var/wwwEnvironment=Set environment variable. Example:Environment=LANG=en_US.UTF-8EnvironmentFile=Load environment variables from file.EnvironmentFile=/etc/sysconfig/httpdStandardOutput=Where to sendSTDOUT. Example:StandardOutput=journalStandardError=Where to sendSTDERR. Example:StandardError=journal
Service Types
These are possible values which go in the Type= field:
simpleThis is the default. Process started byExecStart=is the main process. This is used when the service runs in the foreground, doesn’t fork.forkingProcess forks into background. Systemd waits for parent to exit. Tradition daemons that fork. UsePIDFile=.oneshotProcess runs and exits. Service isactivewhile running. This is for scripts that do one task and exit.notifyLikesimple, but service signals readiness viasd_notify(). This is for services built with Systemd notification.dbusService is ready whenit acquires its D-Bus name. D-Bus activated services.idleLikesimple, but waits until other jobs finish. This is for low-priority startup tasks.
Restart Policies
These are possible values which go in the Restart= field:
noNever. This is default.on-successClean exit (exit code 0).on-failureNon-zero exit, signal, timeout, watchdog.on-abnormalSignal, timeout, watchdog (not exit codes).on-abortUnclean signal (SIGABRT,SIGSEGV, etc).on-watchdogWatchdog timeout only.alwaysAlways, regardless of exit reason.
The [Install] Section
The [Install] section tells systemd what happens when you run systemctl enable. It doesn’t affect runtime behavior, but only controls where symlinks get created:
WantedBy=Target that “wants” this unit (creates symlink). Think of it as “start my service when this target activates, but if it fails, the target still succeeds”. Example:WantedBy=multi-user.target.RequiredBy=Target that “requires” this unit. Think of it as “start my service when this target activates, and if it fails, the target fails too”. Example:RequiredBy=graphical.target.Alias=Alternative names for the unit. Example:Alias=www.service.
How enable works: When you run systemctl enable myservice, Systemd reads the [Install] section and creates a symlink:
/etc/systemd/system/multi-user.target.wants/myservice.service -> /etc/systemd/system/myservice.service
Vendor units live in /usr/lib/systemd/system
If there is no [Install] section, the unit can’t be enabled/disabled, but runs only as a dependency.
Minimal Service Template
[Unit]
Description=My Custom Service
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/myscript.sh
Restart=on-failure
[Install]
WantedBy=multi-user.target
Follow Along Example
Let’s set up a simple service to make sure that the concepts stick. First, write a simple shell script which just does something. If you want the easy way, as root, copy and paste the following heredoc:
cat > /usr/local/bin/myservice.sh << 'EOF'
#!/bin/bash
while true; do
echo "$(date): Running" >> /tmp/myservice.log
sleep 10
done
EOF
chmod +x /usr/local/bin/myservice.sh
Test if your script works by running it with /usr/local/bin/myservice.sh. It will make the terminal busy. Press CTRL+C to stop it and check like this:
[root@server1 ~]# cat /tmp/myservice.log
Sun Jan 11 06:42:17 PM GMT 2026: Running
If it worked like in this example, you’re gold. Next, choose your editor and create a unit file for myservice.sh. In my case I prefer vim (you should too): vim /etc/systemd/system/myservice.service:
[Unit]
Description=A simple service which logs time every 10 sec
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/myservice.sh
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
Alternatively, if you’re feeling lazy, copy and paste the heredoc:
cat > /etc/systemd/system/myservice.service << 'EOF'
[Unit]
Description=A simple service which logs time every 10 sec
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/myservice.sh
Restart=on-failure
RestartSec=3
[Install]
WantedBy=multi-user.target
EOF
To make sure that Systemd recognizes the service, run:
systemctl daemon-reloadsystemctl start myservice.servicesystemctl status myservice.serviceto see that it’s running.If you want it to enable it to always run when booting:
systemctl enable myservice.service.
You could check that the service is running in two ways:
tail -f /tmp/myservice.logand you will see a new line every 10 seconds.journalctl -u myservice -f(this is fancier) and you should see logs coming up every 10 seconds, plus the history of the service.
To stop it, run systemctl stop myservice.service.
Conclusion
In this lesson you have learned what the basic components of a Systemd service unit file are, and how to create a simple service. I hope that this was instructive. More on Systemd will follow. Next week I hope to post about Systemd timers. Thank you for your read!