[How-to] systemd Service Management on Linux: Complete Beginner’s Guide

Mastering systemd service management is essential for anyone administering Linux systems. As the init system used by virtually all modern distributions, systemd controls how services start, stop, and interact. This guide covers the fundamental commands and concepts you need for effective systemd service management.

Table of Contents

What Is systemd and Why It Matters

systemd is the system and service manager that runs as PID 1 on modern Linux distributions. It replaced the traditional SysV init system and provides aggressive parallelization, socket and D-Bus activation, on-demand daemon starting, and transactional dependency-based service control logic. Understanding systemd service management gives you control over the entire service lifecycle.

Every service, mount point, socket, and timer in systemd is represented as a unit. Service units (ending in .service) are the most common type you’ll interact with. The primary tool for managing these units is systemctl.

Essential systemctl Commands for systemd Service Management

The systemctl command is your main interface for systemd service management. It handles everything from starting services to inspecting their state. Below are the most frequently used commands grouped by purpose.

Starting, Stopping, and Restarting Services

These commands control the immediate state of a service. Most require root privileges.

lc-root@ubuntu:~$ sudo systemctl start nginx.service

Starts the nginx service immediately. The .service suffix is optional — systemctl start nginx works identically.

lc-root@ubuntu:~$ sudo systemctl stop nginx.service

Stops the service immediately. Active connections may be terminated abruptly.

lc-root@ubuntu:~$ sudo systemctl restart nginx.service

Performs a stop followed by a start. Use this after configuration changes.

lc-root@ubuntu:~$ sudo systemctl reload nginx.service

Reloads the service configuration without interrupting active connections. Not all services support this.

lc-root@ubuntu:~$ sudo systemctl daemon-reload

Reloads the systemd manager configuration, scanning for new or changed unit files. Run this after creating or modifying unit files.

Enabling and Disabling Services at Boot

Enabling a service creates the necessary symlinks so it starts automatically at boot. Disabling removes those symlinks.

lc-root@ubuntu:~$ sudo systemctl enable nginx.service

Enables nginx to start at boot. The service will not start until the next reboot or until you start it manually.

lc-root@ubuntu:~$ sudo systemctl enable --now nginx.service

Enables and starts the service immediately. The --now flag combines both operations.

lc-root@ubuntu:~$ sudo systemctl disable nginx.service

Disables the service from starting at boot. Does not stop a currently running service.

lc-root@ubuntu:~$ sudo systemctl disable --now nginx.service

Disables and stops the service immediately.

lc-root@ubuntu:~$ sudo systemctl mask nginx.service

Masks the service, making it impossible to start (manually or as a dependency). Use with caution.

lc-root@ubuntu:~$ sudo systemctl unmask nginx.service

Removes the mask, restoring normal behavior.

Checking Service Status and Logs

Inspecting service state and logs is crucial for troubleshooting and verification.

lc-root@ubuntu:~$ systemctl status nginx.service

Shows the current status, recent log lines, and process information. The output includes the load state (loaded/not-found/masked), active state (active/inactive/failed), and the main PID.

lc-root@ubuntu:~$ systemctl is-active nginx.service

Returns active, inactive, failed, or activating. Useful for scripts.

lc-root@ubuntu:~$ systemctl is-enabled nginx.service

Returns enabled, disabled, static, or masked.

lc-root@ubuntu:~$ systemctl list-units --type=service --state=running

Lists all currently running services.

lc-root@ubuntu:~$ systemctl --failed

Lists all units in a failed state. Essential for system health checks.

lc-root@ubuntu:~$ journalctl -u nginx.service

Shows the complete journal logs for the nginx service. Add -f to follow logs in real-time, or -n 50 to limit output.

lc-root@ubuntu:~$ journalctl -u nginx.service --since "1 hour ago"

Filters logs to the last hour. Useful for narrowing down issues.

Working with systemd Unit Files

Unit files define how services behave in systemd service management. They live in three main directories with increasing precedence:

  • /usr/lib/systemd/system/ — vendor-provided units (lowest priority)
  • /run/systemd/system/ — runtime units (lost on reboot)
  • /etc/systemd/system/ — administrator overrides (highest priority)

Never edit files in /usr/lib/systemd/system/ directly. Instead, use override methods described below.

Unit File Structure and Common Directives

A service unit file has three main sections:

[Unit]
Description=My Custom Service
After=network.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/usr/local/bin/my-service
Restart=always
RestartSec=10
User=www-data
Group=www-data

[Install]
WantedBy=multi-user.target

[Unit] section — Metadata and dependencies:

  • Description — Human-readable description shown in systemctl status
  • After — Start this unit after the listed units (ordering only)
  • Requires — Hard dependency; if the required unit fails, this unit fails
  • Wants — Soft dependency; this unit starts regardless of the wanted unit’s state

[Service] section — Service-specific configuration:

  • Type — Startup type (simple, forking, oneshot, notify, dbus, idle)
  • ExecStart — Command to start the service (required)
  • ExecStop — Command to stop the service (optional)
  • Restart — Restart policy (no, always, on-failure, on-abnormal)
  • RestartSec — Delay before restart
  • User/Group — Run as specific user/group
  • WorkingDirectory — Working directory for the service
  • Environment — Environment variables

[Install] section — Installation behavior:

  • WantedBy — Target that should pull in this service (usually multi-user.target)
  • RequiredBy — Target that requires this service

Creating a Custom Service Unit

Let’s create a simple custom service that runs a Python HTTP server.

  1. Create the unit file:
    lc-root@ubuntu:~$ sudo tee /etc/systemd/system/python-web.service > /dev/null <<'EOF'
    [Unit]
    Description=Python HTTP Server
    After=network.target
    
    [Service]
    Type=simple
    ExecStart=/usr/bin/python3 -m http.server 8080
    WorkingDirectory=/var/www/html
    Restart=always
    RestartSec=5
    User=www-data
    Group=www-data
    
    [Install]
    WantedBy=multi-user.target
    EOF
    
  2. Reload systemd and enable the service:
    lc-root@ubuntu:~$ sudo systemctl daemon-reload
    lc-root@ubuntu:~$ sudo systemctl enable --now python-web.service
    
  3. Verify it's running:
    lc-root@ubuntu:~$ systemctl status python-web.service
    lc-root@ubuntu:~$ curl http://localhost:8080
    

Managing Service Dependencies and Ordering

Proper dependency management ensures services start in the correct order and handle failures gracefully.

Hard vs. Soft Dependencies

Use Requires= for mandatory dependencies — if the dependency fails, your service won't start. Use Wants= for optional dependencies — your service starts regardless.

[Unit]
Description=Database-Backed Application
Requires=postgresql.service
After=postgresql.service
Wants=redis.service
After=redis.service

Ordering Without Dependencies

Use Before= and After= alone when you only need ordering, not dependency:

[Unit]
Description=Log Processor
After=network-online.target

Network Dependencies

For services needing network connectivity, use the standard network targets:

[Unit]
Description=My Network Service
Wants=network-online.target
After=network-online.target

Ensure the corresponding wait service is enabled (NetworkManager-wait-online.service, systemd-networkd-wait-online.service, or netctl-wait-online.service depending on your network manager).

Best Practices for systemd Service Management

Following these practices will make your service management more reliable and maintainable.

  • Use drop-in files for overrides: Instead of copying entire unit files to /etc/systemd/system/, create drop-in snippets in /etc/systemd/system/.d/. This preserves vendor updates while applying your customizations. Run systemctl edit to create them easily.
  • Set appropriate restart policies: Use Restart=on-failure for most services to recover from crashes. Use Restart=always only for critical services that must run continuously. Always pair with RestartSec to prevent restart loops.
  • Run services as non-root users: Specify User= and Group= in the [Service] section. Avoid running services as root unless absolutely necessary. Create dedicated system users with systemd-sysusers.
  • Use Type=notify for custom daemons: If you control the daemon code, implement sd_notify and use Type=notify. This lets systemd track readiness precisely, improving boot parallelization.
  • Limit resource usage: Add MemoryMax=, CPUQuota=, and IOWeight= to prevent runaway services from consuming all resources. See systemd.resource-control(5) for details.

Conclusion

Effective systemd service management is a core skill for Linux administrators. The systemctl command provides a consistent interface for controlling service lifecycle, while unit files offer declarative configuration for service behavior. By mastering the commands in this guide — starting, stopping, enabling, checking status, and creating custom units — you'll be equipped to manage services on any modern Linux distribution.

For deeper exploration, consult the official documentation at systemd manual pages and the Arch Wiki systemd page. To continue building your Linux administration skills, consider these related guides:

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.