How To

How to Create a systemd Service File in Linux: Step-by-Step Guide

Systemd is the init system on most modern Linux distributions. A service file (also called a unit file) tells systemd how to start, stop, and manage a process. Creating one is the correct way to run a custom script or application as a managed service with automatic restart, boot integration, and proper logging.

Service files use the .service extension and are plain text files in ini format. Place custom files in /etc/systemd/system/. Files there take priority over package-installed units in /usr/lib/systemd/system/ and survive package upgrades. Never edit files in /usr/lib/systemd/system/ directly — copy them to /etc/systemd/system/ to override.

How to Create and Install a systemd Service File

Create the file:

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

A minimal working service file:

ini[Unit]Description=My Custom ApplicationAfter=network.target[Service]Type=simpleExecStart=/usr/local/bin/myapp.shRestart=on-failureRestartSec=5[Install]WantedBy=multi-user.target

After saving, reload systemd and enable the service:

bashsudo systemctl daemon-reloadsudo systemctl enable --now myapp

Run daemon-reload after every edit to the unit file. Systemd reads the file at reload time, not at start time. Skipping this step is the most common reason why changes have no effect.

Check status and logs:

bashsudo systemctl status myappsudo journalctl -u myapp          # full log historysudo journalctl -fu myapp         # live log stream

Service File Sections: [Unit], [Service], and [Install] Explained

[Unit] contains metadata and dependency declarations:

  • Description= — the name shown in systemctl status output
  • After= — start this service after the listed units are active; this is ordering only, not a dependency
  • Requires= — hard dependency; if the listed unit fails, this service also fails
  • Wants= — soft dependency; service still starts even if the listed unit fails

After=network.target means “wait for networking to be ready” but does not make networking a hard requirement. For a hard requirement, combine After= with Requires=.

[Service] defines the process:

  • ExecStart= — the command to run; must be an absolute path. Use which binary to find the full path if unsure
  • Type= — see the table below
  • Restart= and RestartSec= — restart behavior and delay
  • User= and Group= — run as a specific user instead of root
  • Environment= — set environment variables: Environment="NODE_ENV=production"

[Install] controls enablement:

  • WantedBy=multi-user.target — the standard value for services that start on normal multi-user boot

Service Types, Restart Policies, and Non-Root Execution

Type= tells systemd how the process behaves at startup:

TypeWhen to use
simpleExecStart is the main process; right choice for most custom scripts
forkingProcess forks and the parent exits; use for traditional background daemons
oneshotRuns once and exits; systemd waits for completion before marking the service active
notifyLike simple, but the process signals readiness to systemd via sd_notify()

Restart= controls when systemd automatically restarts the service:

  • on-failure — restart on non-zero exit code, signal, or timeout; most common choice
  • always — restart after any exit, including a clean exit code 0
  • no — never restart (default)

The default RestartSec= is 100ms. Set it to a higher value like RestartSec=5 to avoid rapid restart loops.

Running as a non-root user. Running services as root is a security risk. Use User= and Group= in [Service] and create a dedicated system account first:

bashsudo useradd -r -s /usr/sbin/nologin myappuser

Add to the service file:

iniUser=myappuserGroup=myappuser

If the service is compromised, the process cannot escalate to root privileges.

Place the file in /etc/systemd/system/, run daemon-reload after every change, and check logs with journalctl -u. Use Type=simple and Restart=on-failure for most custom applications, and always run services under a dedicated non-root user. Leave a comment below if you run into any issues.

Cyber Defence

Recent Posts

How to Remove Files and Directories in Linux: rm, shred, rmdir

The command line does not have a Trash folder. When you delete a file from…

38 minutes ago

How to Create Users in Linux with useradd: A Complete Guide

Linux is a multi-user system. Each person or service that needs access should have its…

48 minutes ago

watch Command in Linux: Monitor Changing Output in Real Time

The watch command in Linux runs a command at regular intervals and refreshes the terminal with the…

53 minutes ago

xargs Command in Linux: Build and Execute Commands from Input

The xargs command in Linux reads items from standard input and passes them as arguments to another…

2 days ago

locate Command in Linux: Find Files Fast with a Database Search

The locate command in Linux searches for files and directories by name. It queries a pre-built database…

2 days ago

Listing Linux Services with systemctl: A Complete Guide

Most modern Linux distributions use systemd as the default service manager. Knowing how to list…

2 days ago