Linux - Systemd Service Creation and Management

Systemd is the default initialization and service management system used by most modern Linux distributions. It is responsible for starting system services during boot, managing background processes, handling dependencies, logging service events, and controlling the overall state of the operating system. Before systemd, Linux systems commonly used SysVinit, which relied on shell scripts to start and stop services. Systemd introduced a faster, more organized, and feature-rich approach to service management.

One of the most important features of systemd is the ability to create custom services. Administrators and developers often need to run applications, scripts, or servers automatically during system startup. Instead of manually executing these programs every time the system boots, they can create a systemd service unit that manages the application's lifecycle.

What is a Systemd Service?

A systemd service is defined using a configuration file called a service unit. These files describe how a service should start, stop, restart, and interact with other services.

Service unit files usually have the extension:

.service

Examples include:

apache2.service
sshd.service
mysql.service
nginx.service

Custom services can also be created with names such as:

backup.service
pythonapp.service
monitor.service

Location of Service Files

Systemd searches for service files in several directories.

System-wide services installed by packages:

/usr/lib/systemd/system/

or

/lib/systemd/system/

Custom services created by administrators:

/etc/systemd/system/

Temporary runtime services:

/run/systemd/system/

The recommended location for custom services is:

/etc/systemd/system/

Structure of a Service File

A service file is divided into sections enclosed within square brackets.

The three primary sections are:

[Unit]
[Service]
[Install]

Each section serves a different purpose.

The [Unit] Section

The Unit section provides general information about the service.

Example:

[Unit]
Description=Python Web Application
Documentation=https://example.com
After=network.target
Requires=network.target

Common directives include:

Description

Provides a short explanation of the service.

Description=Backup Service

Documentation

Specifies documentation or reference links.

Documentation=https://example.com/docs

After

Determines which services must start before this service.

Example:

After=network.target

This ensures networking is available before the application starts.

Before

Starts this service before another service.

Example:

Before=apache2.service

Requires

Specifies mandatory dependencies.

Example:

Requires=mysql.service

If MySQL fails, the dependent service also stops.

Wants

Creates a weaker dependency.

Example:

Wants=network-online.target

The service can still continue even if the dependency is unavailable.

The [Service] Section

This section defines how the service operates.

Example:

[Service]
Type=simple
ExecStart=/usr/bin/python3 /opt/app/server.py
Restart=always
RestartSec=5
User=www-data
Group=www-data
WorkingDirectory=/opt/app

Important Directives

ExecStart

Specifies the command used to start the service.

Example:

ExecStart=/usr/bin/python3 app.py

ExecStop

Command executed when stopping the service.

Example:

ExecStop=/bin/kill -15 $MAINPID

ExecReload

Reloads configuration without restarting.

Example:

ExecReload=/bin/kill -HUP $MAINPID

Type

Defines how systemd determines when the service has started.

Common values include:

simple
forking
oneshot
notify
idle

simple

Most common option.

The process starts immediately.

Example:

Type=simple

forking

Used by older daemon programs.

Example:

Type=forking

oneshot

Runs a task once and exits.

Useful for backup scripts.

Example:

Type=oneshot

User

Runs the service as a specific user.

Example:

User=backup

Group

Specifies the group.

Example:

Group=backup

WorkingDirectory

Sets the current working directory.

Example:

WorkingDirectory=/opt/application

Environment

Defines environment variables.

Example:

Environment="PORT=8080"
Environment="MODE=production"

EnvironmentFile

Loads variables from a file.

Example:

EnvironmentFile=/etc/myapp.conf

Restart

Determines restart behavior.

Options include:

no
always
on-success
on-failure
on-abnormal

Example:

Restart=always

RestartSec

Specifies the delay before restarting.

Example:

RestartSec=10

TimeoutStartSec

Limits startup duration.

Example:

TimeoutStartSec=30

TimeoutStopSec

Limits shutdown duration.

Example:

TimeoutStopSec=20

The [Install] Section

This section controls how the service is enabled during system boot.

Example:

[Install]
WantedBy=multi-user.target

WantedBy

Specifies the target under which the service is enabled.

Example:

WantedBy=multi-user.target

This causes the service to start automatically in normal multi-user mode.

Example Custom Service

Suppose a Python application is stored in:

/opt/webapp/app.py

Create:

/etc/systemd/system/webapp.service

Contents:

[Unit]
Description=Python Web Application
After=network.target

[Service]
Type=simple
User=ubuntu
WorkingDirectory=/opt/webapp
ExecStart=/usr/bin/python3 /opt/webapp/app.py
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Reloading Systemd

Whenever a new service file is created or modified, systemd must reload its configuration.

Command:

sudo systemctl daemon-reload

Without this step, systemd continues using the old configuration.

Starting a Service

sudo systemctl start webapp.service

The service starts immediately.

Stopping a Service

sudo systemctl stop webapp.service

The service terminates safely.

Restarting a Service

sudo systemctl restart webapp.service

Useful after configuration changes.

Reloading a Service

sudo systemctl reload webapp.service

Only works if the application supports configuration reloads.

Enabling Automatic Startup

To start the service during every system boot:

sudo systemctl enable webapp.service

Systemd creates symbolic links internally.

Disabling Automatic Startup

sudo systemctl disable webapp.service

The service remains installed but no longer starts automatically.

Checking Service Status

systemctl status webapp.service

Output includes:

  • Active or inactive status

  • Process ID (PID)

  • Memory usage

  • CPU usage

  • Recent log messages

  • Service start time

  • Exit status

This command is the primary tool for monitoring service health.

Viewing Service Logs

Systemd integrates with the journal logging system.

To view logs:

journalctl -u webapp.service

To monitor logs in real time:

journalctl -u webapp.service -f

Logs include startup messages, errors, warnings, and application output if it is sent to standard output or standard error.

Managing Service Dependencies

Systemd allows services to start in a controlled order.

Example:

After=network.target
Requires=mysql.service

This ensures the network starts before the application and that the application depends on the MySQL service.

Other useful dependency directives include:

Before=
Wants=
PartOf=
BindsTo=
Conflicts=

These directives help coordinate service startup, shutdown, and relationships between services.

Service Targets

A target groups multiple services together and represents a specific system state.

Common targets include:

  • multi-user.target – Standard multi-user, non-graphical mode.

  • graphical.target – Graphical desktop environment.

  • network.target – Basic networking initialized.

  • network-online.target – Network fully configured and online.

  • rescue.target – Single-user rescue mode.

  • emergency.target – Minimal emergency environment.

Services can be associated with these targets to control when they start.

Troubleshooting Common Issues

Some common issues encountered while creating systemd services include:

  • Incorrect path specified in ExecStart, causing the service to fail to launch.

  • Missing execute permissions on scripts or binaries.

  • Running the service under a user account that lacks permission to access required files or directories.

  • Forgetting to run systemctl daemon-reload after modifying the service file.

  • Missing dependencies, resulting in startup failures.

  • Invalid syntax in the service file, which prevents systemd from loading it.

Commands such as systemctl status and journalctl are essential for diagnosing these problems by providing detailed status information and logs.

Advantages of Systemd Service Management

Systemd provides a centralized and efficient way to manage services across the Linux operating system. It supports automatic startup at boot, dependency handling, service monitoring, automatic restarts after failures, integrated logging through the journal, resource control, and improved boot performance through parallel service initialization. These capabilities make it easier for administrators to deploy, maintain, and troubleshoot applications and background services in both small systems and large enterprise environments.