Skip to content

Systemd Unit File Builder(1)

Name

Build systemd .service unit files visually β€” configure Unit, Service, and Install sections with dropdowns and inputs, then copy the generated file.

Presets

Service Name

[Unit] Section

[Service] Section

[Install] Section

Generated Unit File

myapp.service

[Unit]
After=network.target

[Service]
Type=simple
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

Installation Commands

1. Save the unit file:

sudo nano /etc/systemd/system/myapp.service

2. Reload systemd daemon:

sudo systemctl daemon-reload

3. Enable the service (start on boot):

sudo systemctl enable myapp.service

4. Start the service:

sudo systemctl start myapp.service

5. Check status:

sudo systemctl status myapp.service

6. View logs:

journalctl -u myapp.service -f
sponsored

Guide

What is a systemd service file?

A systemd unit file is an INI-style configuration that tells the Linux init system how to start, stop, and supervise a process. It defines dependencies, restart policies, resource limits, and environment variables β€” replacing older init scripts with a declarative, standardized format.

How to use this builder

Pick an application preset (Node.js, Python, Go, Docker, etc.) or start blank. Fill in the Unit, Service, and Install sections using the form fields β€” set the ExecStart command, restart policy, user, working directory, and more. Copy the generated file to /etc/systemd/system/ and run systemctl daemon-reload to activate it.

Why use a unit file builder?

Writing systemd unit files by hand means memorizing dozens of directives and their valid values. This builder surfaces the most common options with sensible defaults, helping you create reliable service files without consulting the man pages every time.

Where do unit files go?

Put your own units in /etc/systemd/system/ β€” that directory overrides the packaged units in /usr/lib/systemd/system/ (/lib/systemd/system/ on older Debian and Ubuntu). Per-user services go in ~/.config/systemd/user/ and are managed with systemctl --user. After creating or editing a file, run systemctl daemon-reload so systemd rereads it, then systemctl enable --now myapp.service to start it now and on every boot. To change a packaged unit without editing it, use systemctl edit myapp, which writes a drop-in to /etc/systemd/system/myapp.service.d/override.conf.

Type=simple, exec, forking, oneshot or notify?

Type=simple (the default) treats the service as started the moment the process is launched. Type=exec waits until the binary has actually been executed, so a wrong path is reported as a failed start instead of a later crash. Use Type=forking only for old-style daemons that background themselves, usually together with PIDFile=. Type=oneshot is for scripts that run and exit β€” add RemainAfterExit=yes if the unit should stay active afterwards. Type=notify is for applications that tell systemd they are ready via sd_notify.

Restart policies and restart loops

Restart=on-failure restarts the service when it exits non-zero, is killed by a signal or times out, and is the right default for most applications; Restart=always also restarts after a clean exit. Add RestartSec=5 so a crashing service doesn't spin. systemd also rate-limits restarts: by default a unit that starts more than 5 times in 10 seconds is marked failed. Tune that with StartLimitIntervalSec= and StartLimitBurst= in the [Unit] section, and clear the failed state with systemctl reset-failed myapp.

Run as a non-root user and harden the service

Set User= and Group= so the process doesn't run as root, or use DynamicUser=yes to have systemd allocate a throwaway user at start. Sandboxing directives cut down what a compromised service can touch: NoNewPrivileges=yes, PrivateTmp=yes, ProtectSystem=strict (the whole filesystem read-only except /dev, /proc and /sys), ProtectHome=yes, plus ReadWritePaths= for the directories it really needs. Run systemd-analyze security myapp.service to see an exposure score and which protections are still missing.

Environment variables and secrets

Environment=NODE_ENV=production sets a variable inline; EnvironmentFile=/etc/myapp/env loads KEY=value lines from a file, and a leading dash (EnvironmentFile=-/etc/myapp/env) makes the file optional. Keep secrets out of the unit file itself β€” unit files are world-readable β€” and make the environment file owned by root with mode 0600. systemctl show myapp -p Environment prints what systemd will pass to the process.

Why won't my service start?

Start with systemctl status myapp for the last log lines and the exit code, then journalctl -u myapp -e for the full log (add -f to follow it live). status=203/EXEC means systemd couldn't execute the ExecStart command β€” usually a relative path, a missing binary or a script without the executable bit; ExecStart needs an absolute path. status=217/USER means the User= account doesn't exist. systemd-analyze verify /etc/systemd/system/myapp.service catches typos and unknown directives before you start the unit.

See also