systemd Unit File Generator
Build a complete .service, .timer, or .socket unit file with a visual form.
Client-side only. Nothing leaves your browser
[Unit]
Final filename: myapp.service
Optional. man:, https://, or file://
Order only
Soft dep
Hard dep
[Service]
Absolute path required
Optional pre-start command
Optional stop command
Path to env file
Seconds before restart
[Install]
[Unit] Description=My application service After=network.target [Service] Type=simple ExecStart=/usr/bin/myapp --flag WorkingDirectory=/opt/myapp User=myapp Environment=NODE_ENV=production Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target
Install steps
- 1. Save as
/etc/systemd/system/myapp.service - 2.
sudo systemctl daemon-reload - 3.
sudo systemctl enable --now myapp.service - 4.
sudo systemctl status myapp.service
For user-level units, save to ~/.config/systemd/user/ and use systemctl --user.
What is a systemd Unit File?
A systemd unit file is a plain-text configuration file that tells the systemd init system how to manage a resource on a Linux machine. The most common type is the .service unit, which defines a long-running process (a daemon), but systemd also manages .timer units (scheduled jobs, the modern replacement for cron), .socket units (socket-activated services), mounts, devices, and targets. Every unit file is divided into sections like [Unit], [Service], and [Install], each containing key=value directives.
Where systemd Unit Files Live
systemd searches several paths for unit files. Order matters: later directories override earlier ones.
| Path | Purpose |
|---|---|
| /usr/lib/systemd/system/ | Units installed by the OS or distro packages. Do not edit. |
| /etc/systemd/system/ | System-wide units you create. This is where your custom .service files go. |
| /run/systemd/system/ | Runtime-only units, gone after reboot. |
| ~/.config/systemd/user/ | Per-user units managed with systemctl --user. |
systemd Service Types
The Type= directive controls how systemd decides your process has finished starting up.
| Type | When to use |
|---|---|
| simple | Default. Process started by ExecStart is the main process. Use for most foreground apps. |
| exec | Like simple, but waits until the binary has been exec'd before considering startup complete. |
| forking | Traditional daemons that fork into the background. Usually requires PIDFile=. |
| oneshot | Short-lived task that runs once and exits. Pair with RemainAfterExit=yes if needed. |
| notify | Service signals readiness with sd_notify(). Best for apps that support it (e.g. nginx with sd-daemon). |
| dbus | Service is ready once it acquires a D-Bus name. |
| idle | Like simple, but waits for active jobs to finish. Useful to keep boot output clean. |
Restart Policy Options
| Policy | Restarts when |
|---|---|
| no | Never restart automatically. |
| always | Always restart, regardless of exit reason. Use with caution. |
| on-success | Process exits cleanly (exit code 0). |
| on-failure | Non-zero exit, killed by signal, or timeout. Recommended for most services. |
| on-abnormal | Killed by signal or timeout (not on non-zero exit). |
| on-watchdog | Watchdog timeout expired. Pair with WatchdogSec=. |
| on-abort | Service was aborted by an uncaught signal. |
OnCalendar Schedule Examples
systemd timers use OnCalendar= with a calendar event format. It's more readable than cron syntax.
| OnCalendar | Meaning |
|---|---|
| minutely | Every minute |
| hourly | Every hour at :00 |
| daily | Every day at 00:00 |
| weekly | Every Monday at 00:00 |
| monthly | First day of every month at 00:00 |
| *-*-* *:00:00 | Every hour on the hour |
| *-*-* *:0/15:00 | Every 15 minutes |
| Mon..Fri *-*-* 09:00:00 | Weekdays at 9am |
| *-*-01 03:00:00 | 1st of every month at 3am |
| Sat *-*-* 02:30:00 | Every Saturday at 2:30am |
Frequently Asked Questions
What is a systemd unit file?
A systemd unit file is a plain-text INI-style configuration file that tells systemd how to manage a resource, usually a service (daemon), but also timers, sockets, mounts, devices, and targets. Each unit file lives at a path like /etc/systemd/system/myapp.service and is divided into sections in square brackets: [Unit] for metadata and ordering, a type-specific section ([Service], [Timer], or [Socket]), and [Install] for enable/disable behavior. systemd reads these files when you run 'systemctl daemon-reload' and uses them whenever you start, stop, enable, or check the status of a unit.
Where should I put my systemd unit file?
Custom system-wide units go in /etc/systemd/system/. That directory takes precedence over /usr/lib/systemd/system/ (which is reserved for unit files installed by distro packages, so don't edit those directly). Per-user units go in ~/.config/systemd/user/ and are managed with 'systemctl --user'. /run/systemd/system/ exists for runtime-only units that disappear on reboot. After dropping a new file in /etc/systemd/system/, run 'sudo systemctl daemon-reload' so systemd picks it up.
What is the difference between a systemd unit and a service?
A unit is the generic term for anything systemd manages: services, timers, sockets, mounts, paths, devices, slices, scopes, and targets are all unit types. A service is one specific kind of unit, defined by a .service file, that represents a process or daemon systemd starts and supervises. So every service is a unit, but not every unit is a service. The 'systemctl list-units' command shows all unit types, while 'systemctl list-units --type=service' filters to just services.
Do systemd unit files need to be executable?
No. Unit files are configuration, not scripts. They should have permissions like 644 (readable by all, writable by root). The binary or script referenced by ExecStart= must be executable, but the .service file itself does not. If you set the unit file as executable systemd will still load it, but it's wrong by convention and can confuse other admins. Use 'chmod 644 /etc/systemd/system/myapp.service' if in doubt.
Why does my systemd service fail with status 203/EXEC?
Status 203/EXEC means systemd could not execute the binary specified in ExecStart=. The most common causes are: (1) the path is not absolute (ExecStart must start with '/'); (2) the file does not exist at that path; (3) the file exists but is not executable, so run 'chmod +x /path/to/binary'; (4) the User= you set does not have execute permission on the file or search permission on a parent directory; (5) the binary is a script with a missing or invalid shebang line. Check 'journalctl -xeu yourservice.service' for the exact reason and verify the path with 'ls -l'.
Related Tools
Unit File Validator
Validate systemd unit files. Paste a .service, .timer, .socket, or .mount file and catch missing directives, bad syntax, and errors.
PM2 Ecosystem Generator
Visual builder for ecosystem.config.js. Configure cluster mode, env vars, watch, and max_memory_restart.
PM2 to systemd
Convert a PM2 app entry into a systemd .service unit file with cluster template support.
Cron Generator
Generate, validate, and translate cron expressions. Visual cron builder with human-readable descriptions.
Cron to systemd Timer
Convert cron expressions to systemd .service and .timer files with OnCalendar syntax.
Need to manage SSH connections?
SSH Workbench lets you connect, browse files, and manage servers visually.
Try SSH Workbench Free