How to Create a systemd Service File in Linux
systemd is the init system used by most modern Linux distributions, including Ubuntu, Debian, Fedora, and RHEL. It manages system processes, handles service dependencies, and starts services automatically at boot.
A systemd service file — also called a unit file — tells systemd how to start, stop, and manage a process. This guide explains how to create a systemd service file, install it on the system, and manage it with systemctl.
Quick Reference
| Task | Command |
|---|---|
| Create a service file | sudo nano /etc/systemd/system/myservice.service |
| Reload systemd after changes | sudo systemctl daemon-reload |
| Enable service at boot | sudo systemctl enable myservice |
| Start the service | sudo systemctl start myservice |
| Enable and start at once | sudo systemctl enable --now myservice |
| Check service status | sudo systemctl status myservice |
| Stop the service | sudo systemctl stop myservice |
| Disable at boot | sudo systemctl disable myservice |
| View service logs | sudo journalctl -u myservice |
| View live logs | sudo journalctl -fu myservice |
Understanding systemd Unit Files
Service files are plain text files with an .service extension. They are stored in one of two locations:
-
/etc/systemd/system/— system-wide services, managed by root. Files here take priority over package-installed units. -
/usr/lib/systemd/system/or/lib/systemd/system/— units installed by packages, depending on the distribution. Do not edit these directly; copy them to/etc/systemd/system/to override.
A service file is divided into three sections:
-
[Unit]— describes the service and declares dependencies. -
[Service]— defines how to start, stop, and run the process. -
[Install]— controls how and when the service is enabled.
Creating a Simple Service File
In this example, we will create a service that runs a custom Bash script. First, create the script you want to run:
sudo nano /usr/local/bin/myapp.shAdd the following content to the script:
#!/bin/bash
echo "myapp started" >> /var/log/myapp.log
# your application logic here
exec /usr/local/bin/myappMake the script executable:
sudo chmod +x /usr/local/bin/myapp.shNow create the service file:
sudo nano /etc/systemd/system/myapp.serviceAdd the following content:
[Unit]
Description=My Custom Application
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/myapp.sh
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.targetAfter saving the file, reload systemd to pick up the new unit:
sudo systemctl daemon-reloadEnable and start the service:
sudo systemctl enable --now myappCheck that it is running:
sudo systemctl status myapp● myapp.service - My Custom Application
Loaded: loaded (/etc/systemd/system/myapp.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2026-03-10 09:00:00 CET; 2s ago
Main PID: 1234 (myapp.sh)
Tasks: 1 (limit: 4915)
CGroup: /system.slice/myapp.service
└─1234 /bin/bash /usr/local/bin/myapp.sh
Unit File Sections Explained
[Unit] Section
The [Unit] section contains metadata and dependency declarations.
Common directives:
-
Description=— a short human-readable name shown insystemctl statusoutput. -
After=— start this service only after the listed units are active. Does not create a dependency; useRequires=for hard dependencies. -
Requires=— this service requires the listed units. If they fail, this service fails too. -
Wants=— likeRequires=, but the service still starts even if the listed units fail. -
Documentation=— a URL or man page reference for the service.
[Service] Section
The [Service] section defines the process and how systemd manages it.
Common directives:
-
Type=— the startup type. See Service Types below. -
ExecStart=— the command to run when the service starts. Must be an absolute path. -
ExecStop=— the command to run when the service stops. If omitted, systemd sendsSIGTERM. -
ExecReload=— the command to reload the service configuration without restarting. -
Restart=— when to restart automatically. See Restart Policies below. -
RestartSec=— how many seconds to wait before restarting. Default is 100ms. -
User=— run the process as this user instead of root. -
Group=— run the process as this group. -
WorkingDirectory=— set the working directory for the process. -
Environment=— set environment variables:Environment="KEY=value". -
EnvironmentFile=— read environment variables from a file.
[Install] Section
The [Install] section controls how the service is enabled.
-
WantedBy=multi-user.target— the most common value. Enables the service for normal multi-user (non-graphical) boot. -
WantedBy=graphical.target— use this if the service requires a graphical environment.
Service Types
The Type= directive tells systemd how the process behaves at startup.
| Type | Description |
|---|---|
simple |
Default. The process started by ExecStart is the main process. |
forking |
The process forks and the parent exits. systemd tracks the child. Use with traditional daemons. |
oneshot |
The process runs once and exits. systemd waits for it to finish before marking the service as active. |
notify |
Like simple, but the process notifies systemd when it is ready using sd_notify(). |
idle |
Like simple, but the process is delayed until all active jobs finish. |
For most custom scripts and applications, Type=simple is the right choice.
Restart Policies
The Restart= directive controls when systemd automatically restarts the service.
| Value | Restarts when |
|---|---|
no |
Never (default). |
always |
The process exits for any reason. |
on-failure |
The process exits with a non-zero code, is killed by a signal, or times out. |
on-abnormal |
Killed by a signal or times out, but not clean exit. |
on-success |
Only if the process exits cleanly (exit code 0). |
For long-running services, Restart=on-failure is the most common choice. Use Restart=always for services that must stay running under all circumstances.
Running a Service as a Non-Root User
Running services as root is a security risk. Use the User= and Group= directives to run the service as a dedicated user:
[Unit]
Description=My Custom Application
After=network.target
[Service]
Type=simple
User=myappuser
Group=myappuser
ExecStart=/usr/local/bin/myapp
Restart=on-failure
WorkingDirectory=/opt/myapp
Environment="NODE_ENV=production"
[Install]
WantedBy=multi-user.targetCreate the system user before enabling the service:
sudo useradd -r -s /usr/sbin/nologin myappuserTroubleshooting
Service fails to start — “Failed to start myapp.service”
Check the logs with journalctl
: sudo journalctl -u myapp --since "5 minutes ago". The output shows the exact error message from the process.
Changes to the service file have no effect
You must run sudo systemctl daemon-reload after every edit to the unit file. systemd reads the file at reload time, not at start time.
“ExecStart= must be an absolute path”
The ExecStart= value must start with /. Use the full path to the binary — for example /usr/bin/python3 not python3. Use which python3 to find the absolute path.
Service starts but immediately exits
The process may be crashing on startup. Check sudo journalctl -u myapp -n 50 for error output. If Type=simple, make sure ExecStart= runs the process in the foreground — not a script that launches a background process and exits.
Service does not start at boot despite being enabled
Confirm the [Install] section has a valid WantedBy= target and that systemctl enable was run after daemon-reload. Check with systemctl is-enabled myapp.
FAQ
Where should I put my service file?
Put custom service files in /etc/systemd/system/. Files there take priority over package-installed units in /usr/lib/systemd/system/ and persist across package upgrades.
What is the difference between enable and start?systemctl start starts the service immediately for the current session only. systemctl enable creates a symlink so the service starts automatically at boot. To do both at once, use systemctl enable --now myservice.
How do I view logs for my service?
Use sudo journalctl -u myservice to see all logs. Add -f to follow live output, or --since "1 hour ago" to limit the time range. See the journalctl guide
for full usage.
Can I run a service as a regular user without root?
Yes, using user-level systemd units stored in ~/.config/systemd/user/. Manage them with systemctl --user enable myservice. They run when the user logs in and stop when they log out (unless lingering is enabled with loginctl enable-linger username).
How do I reload a service after changing its configuration?
If the service supports it, use sudo systemctl reload myservice — this sends SIGHUP or runs ExecReload= without restarting the process. Otherwise, use sudo systemctl restart myservice.
Conclusion
Creating a systemd service file gives you full control over how and when your process runs — including automatic restarts, boot integration, and user isolation. Once the file is in place, use systemctl enable --now to activate it and journalctl -u
to monitor it. For scheduling tasks that run once at a set time rather than continuously, consider cron jobs
as an alternative.







