🔒 All tools run entirely in your browser. No data leaves your device.

systemd Unit Builder

Generate systemd .service and .timer unit files. Hardening flags built in. Presets for web apps, periodic jobs, and one-shot tasks.

[Unit]

[Service]

Hardening

Sandbox the service. Most flags are safe for typical apps; a few break service that do unusual things — test before shipping.

[Install]

[Unit]
Description=Long-running web application
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/usr/local/bin/myapp
WorkingDirectory=/var/lib/myapp
User=myapp
Group=myapp
Restart=on-failure
RestartSec=5

# Hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true

[Install]
WantedBy=multi-user.target

Save as /etc/systemd/system/my-app.service then run systemctl daemon-reload && systemctl enable --now my-app.service.

About this tool

systemd units are conceptually simple — three sections, key=value pairs — but in practice every flag has consequences and the hardening surface is huge. This builder gives you a form for the pieces you usually need (Description, ExecStart, User, Restart), plus a checklist of sandbox flags that improve security without breaking most services.

Three presets cover the common cases: a long-running web app (simple service, restart on failure, network-online dependency, sane hardening defaults), a periodic job (one-shot, paired with a timer), and a one-shot administrative task. Pick a preset, tweak what is wrong, copy the output.

The hardening checkboxes correspond to systemd directives that Mozilla and the systemd developers recommend for nearly every service. ProtectSystem=strict alone is one of the single biggest security wins available in systemd — combined with NoNewPrivileges and PrivateTmp, it puts a network-facing service on solid ground without any code changes.

For timer units, OnCalendar accepts both shortcuts (hourly, daily, weekly) and the full form (Mon..Fri 09:00, *-*-* 02:30:00). Test with systemd-analyze calendar 'expression' before deploying.

Frequently asked questions

Where do I save the generated unit?

For system-wide units, /etc/systemd/system/your-app.service. For user-scoped units (managed without root), ~/.config/systemd/user/your-app.service. Run systemctl daemon-reload after creating or editing.

What is the right Type for a typical web app?

simple if your binary just runs and stays in the foreground (most modern apps). forking only if the program double-forks itself (rare nowadays). exec is like simple but waits for the binary to actually exec before considering startup complete. notify if your code calls sd_notify(READY=1) once it is up.

When should I enable each hardening flag?

Most flags are safe for typical web/API/job services. Test before shipping: ProtectKernelModules breaks anything that loads modules; PrivateDevices breaks programs that need /dev/kvm or /dev/nvidia*; MemoryDenyWriteExecute breaks JIT runtimes (Node, JVM, .NET). Mozilla Observatory and systemd-analyze security give a per-unit risk score.

How does Persistent=true on a timer work?

systemd records when each timer last ran. With Persistent=true, after a reboot or any downtime, the timer fires once if a scheduled run was missed. Without it, missed runs are silently dropped.

How do I handle environment variables that change per deployment?

Put them in a separate file (often /etc/default/your-app) and reference it with EnvironmentFile=. The Environment= field is for values you commit to source control. Don’t put secrets in unit files — use a credential manager and load with LoadCredential.