IT infrastructure calculators

systemd Service File Generator

Fill in a few fields to get a correct, safely escaped systemd .service unit and the commands to install it.

Hardening (test before production)

Unit file: myapp.service

[Unit]
Description=My application

[Service]
Type=simple
ExecStart=/usr/local/bin/myapp --port 8080
User=myapp
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Install and start

Create the file at /etc/systemd/system/myapp.service, paste the unit into it, save, then reload and start:

sudo nano /etc/systemd/system/myapp.service
sudo systemctl daemon-reload
sudo systemctl enable --now myapp.service
systemctl status myapp.service
journalctl -u myapp.service -f

Learn more

How it works

A service unit has three sections: [Unit] describes it and sets ordering, [Service] says what to run and how to restart it, and [Install] says which target enables it at boot.

systemd does not run commands through a shell. It splits the command line itself using the rules in systemd.syntax, expands $VARIABLES from Environment= lines, and treats % as a specifier. The generator handles this for you:

  • Every % you type becomes %%, so date formats and URLs survive.
  • Environment values are quoted, with quotes and backslashes escaped.
  • With "Run through /bin/sh" ticked, the command is wrapped in /bin/sh -c '...' with quotes escaped and $ doubled, so the shell sees exactly what you typed.
  • Line breaks and control characters are rejected in every field, so nothing you type can add an extra line or section.

Output is checked with systemd-analyze verify. Settings follow systemd.service.

Worked example

To run a backup script every time the machine boots, as root, once, logging a dated line:

  • Command: echo "backup $(date +%F)" >> /var/log/backup.log, with "Run through /bin/sh" ticked because of the redirect and $( )
  • Type: oneshot, Restart: no

The generator writes ExecStart=/bin/sh -c 'echo "backup $$(date +%%F)" >> /var/log/backup.log'. systemd turns $$ back into $ and %% back into %, so the shell receives your original command.

Where do I put a systemd service file?

System services go in /etc/systemd/system/. Per-user services go in ~/.config/systemd/user/ and are managed with systemctl --user.

What is the difference between Type=simple and Type=exec?

Both are for programs that stay in the foreground. With exec, systemctl start waits until the program has actually been started, so a wrong path is reported as a failed start instead of an immediate exit.

Why does my pipe or redirect not work in ExecStart?

systemd does not use a shell, so |, >, && and ; are passed to the program as plain text. Run the command through /bin/sh -c, or move it into a script.

Should I use Restart=always?

For long-running daemons, on-failure is usually enough and avoids restart loops when the program exits on purpose. systemd refuses always for Type=oneshot.

Does the service start at boot?

Only after systemctl enable. The generated commands use enable --now, which enables it for boot and starts it right away.