[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
- Essential systemctl Commands for Service Management
- Starting, Stopping, and Restarting Services
- Enabling and Disabling Services at Boot
- Checking Service Status and Logs
- Working with systemd Unit Files
- Unit File Structure and Common Directives
- Creating a Custom Service Unit
- Managing Service Dependencies and Ordering
- Best Practices for systemd Service Management
- Conclusion
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 insystemctl statusAfter— Start this unit after the listed units (ordering only)Requires— Hard dependency; if the required unit fails, this unit failsWants— 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 restartUser/Group— Run as specific user/groupWorkingDirectory— Working directory for the serviceEnvironment— Environment variables
[Install] section — Installation behavior:
WantedBy— Target that should pull in this service (usuallymulti-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.
- 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
- Reload systemd and enable the service:
lc-root@ubuntu:~$ sudo systemctl daemon-reload lc-root@ubuntu:~$ sudo systemctl enable --now python-web.service
- 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/. This preserves vendor updates while applying your customizations. Run.d/ systemctl editto create them easily. - Set appropriate restart policies: Use
Restart=on-failurefor most services to recover from crashes. UseRestart=alwaysonly for critical services that must run continuously. Always pair withRestartSecto prevent restart loops. - Run services as non-root users: Specify
User=andGroup=in the[Service]section. Avoid running services as root unless absolutely necessary. Create dedicated system users withsystemd-sysusers. - Use Type=notify for custom daemons: If you control the daemon code, implement
sd_notifyand useType=notify. This lets systemd track readiness precisely, improving boot parallelization. - Limit resource usage: Add
MemoryMax=,CPUQuota=, andIOWeight=to prevent runaway services from consuming all resources. Seesystemd.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: