Security Tools

Systemd Service File Generator

Generate systemd unit files for Linux services.

beginner5 minRuns in your browser

Interactive workspace

Inputs stay on your device — nothing is sent to our servers unless you choose to share.

Client-side only

Service configuration

Live preview

/etc/systemd/system/my-app.service

Type=simple · User=www-data · Restart=on-failure

[Unit]
Description=My application service
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/app
Environment=NODE_ENV=production
ExecStart=/usr/bin/node /opt/app/server.js
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Enable & start

# Install unit file to /etc/systemd/system/my-app.service
sudo cp my-app.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable my-app
sudo systemctl start my-app
sudo systemctl status my-app
Save the unit file on your server, run systemctl daemon-reload, then enable and start. For web apps, pair with Nginx as a reverse proxy — bind your app to localhost only.

Documentation

How to use this tool, practical use cases, and technical notes.

Generating a production-ready systemd unit file takes under 5 minutes. Here is a complete walkthrough of every field, what it controls, and how to choose the right value.

Step 1 — Choose a Template (or Start Blank)

The tool offers five quick-start templates at the top of the configuration panel. Clicking a template pre-fills all fields with appropriate values for that service type. You can then customize any field. The templates available are:

  • Node.js web app — for Express, Fastify, NestJS, Next.js and similar Node runtimes

  • Python API — for Flask, FastAPI, Django + Gunicorn and similar Python web servers

  • Docker Compose — for starting a docker compose up stack as a system service

  • Backup job — for shell scripts or Python scripts that run once and exit

  • Static + Nginx — for Nginx configured to serve static files

If none of these match your use case, leave the defaults and fill in the fields manually.

Step 2 — Fill in the Configuration Fields

Service Name

The name used for the unit file filename and for systemctl commands. Use lowercase letters, numbers, and hyphens — no spaces.

Example Input

Resulting File

systemctl Command

my-app

/etc/systemd/system/my-app.service

systemctl start my-app

api-server

/etc/systemd/system/api-server.service

systemctl status api-server

backup-daily

/etc/systemd/system/backup-daily.service

systemctl enable backup-daily

Description

A human-readable string that describes what the service does. Shown in systemctl status output and in journalctl log headers. Keep it concise but descriptive — this is the first thing a sysadmin sees when investigating a service.

ExecStart

The absolute path to the binary (and any arguments) that systemd will execute to start the service. This is the most critical field.

Runtime

Correct ExecStart Format

Find Binary With

Node.js

/usr/bin/node /opt/app/server.js

which node

Python (Gunicorn)

/usr/bin/gunicorn -w 4 -b 0.0.0.0:8000 app:app

which gunicorn

Python (direct)

/usr/bin/python3 /opt/api/main.py

which python3

Bash script

/bin/bash /opt/scripts/backup.sh

N/A

Docker Compose

/usr/bin/docker compose -f /opt/app/docker-compose.yml up

which docker

Nginx

/usr/sbin/nginx -g 'daemon off;'

which nginx

Important: Always use the full absolute path. Relative paths and shell aliases do not work in ExecStart. Use which <binary> on your server to confirm the correct path.

Run As User

Option

UID

When to Use

Security Risk

www-data

33 (Debian/Ubuntu)

Web servers, APIs serving HTTP traffic

Low — unprivileged

nobody

65534

Services that need no filesystem write access

Lowest — most restricted

root

0

Services that genuinely require system-level access

High — use only when necessary

Custom user

Variable

Dedicated service account (recommended for production)

Low if configured correctly

Best practice: Create a dedicated system user for each service (sudo useradd --system --no-create-home myapp) and use that account. This limits blast radius if the service is compromised.

Service Type

This is the most commonly misconfigured field. Choosing the wrong type causes the service to be considered "started" at the wrong time, leading to dependency failures or infinite restart loops.

Type

Behavior

When to Use

Common Examples

simple

Process started by ExecStart IS the main process; systemd considers the service running immediately

Long-running foreground processes

Node.js, Python Flask/FastAPI, most modern apps

forking

Service forks a child process and the parent exits; systemd tracks the child

Traditional Unix daemons

Nginx, Apache, classic sysvinit-style daemons

oneshot

Service runs once and exits; systemd waits for it to complete before proceeding

Initialization scripts, backup jobs, one-time tasks

Database migrations, backup scripts, setup tasks

notify

Like simple, but service explicitly calls sd_notify() to signal readiness

Services that take time to initialize before accepting connections

PostgreSQL, systemd-aware services

idle

Execution delayed until all active jobs are dispatched

Services that should start last, after everything else

Low-priority cleanup or telemetry services

After (Dependency)

Controls startup ordering — what systemd must start (or attempt to start) before this service is launched.

Target

Meaning

When to Use

network.target

Basic network interfaces are up

Any service that makes outbound network calls

network-online.target

Network is fully online and routable

Services that fail if the network is not reachable at startup

multi-user.target

System has reached multi-user mode (all standard services running)

Services with no specific dependency

docker.service

Docker daemon is running

Any service that depends on Docker

postgresql.service

PostgreSQL is running

Application servers that require a database connection at startup

Note: After= only controls ordering, not hard dependency. Use Requires= or Wants= if you need systemd to also ensure the dependency is running, not just started first.

Restart Policy

Policy

Restarts On

Does Not Restart On

Best For

no

Nothing

Everything

One-shot jobs, scripts you manage manually

on-failure

Non-zero exit, signal, timeout

Clean exit (code 0)

Production web apps and APIs

on-abnormal

Signals, watchdog timeout, core dumps

Clean or error exit

Services where crashes need recovery but normal exits don't

always

Everything including clean exit

Nothing

Services that should never be allowed to stay stopped

on-success

Clean exit only (code 0)

Failures

Unusual; rarely the right choice

Working Directory

The directory systemd will chdir into before executing ExecStart. If your application loads relative config paths (e.g., ./config.json), this must point to your app's root directory.

Environment Variables

One KEY=VALUE pair per line. These are injected into the service process's environment. Sensitive values (database passwords, API keys) should ideally be stored in a separate environment file (EnvironmentFile=/etc/myapp/env) rather than directly in the unit file, to control permissions separately.

Step 3 — Read the Live Preview

The unit file preview updates in real time as you change any field. Review it for:

  • Correct ExecStart absolute path

  • Expected User and Type values

  • Correct After= target for your dependencies

  • RestartSec=5 (auto-included) — the delay between restart attempts

Step 4 — Copy the Unit File

Click "Copy unit" to copy the generated .service file contents to your clipboard.

Step 5 — Deploy Using the Generated Commands

The "Enable & start" section generates the exact shell commands for your service name:

# Install unit file to /etc/systemd/system/my-app.service
sudo cp my-app.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable my-app
sudo systemctl start my-app
sudo systemctl status my-app

Command

What It Does

sudo cp my-app.service /etc/systemd/system/

Installs the unit file to the correct location

sudo systemctl daemon-reload

Tells systemd to re-read all unit files (required after any change)

sudo systemctl enable my-app

Creates symlinks so the service starts automatically at boot

sudo systemctl start my-app

Starts the service immediately (without waiting for reboot)

sudo systemctl status my-app

Verifies the service is active and shows recent log lines

Useful Post-Deployment Commands

Task

Command

View live service logs

journalctl -u my-app -f

View last 100 log lines

journalctl -u my-app -n 100

Stop the service

sudo systemctl stop my-app

Restart the service

sudo systemctl restart my-app

Reload config without restart

sudo systemctl reload my-app

Disable autostart at boot

sudo systemctl disable my-app

Check service file syntax

systemd-analyze verify /etc/systemd/system/my-app.service

Check all failed services

systemctl --failed