How Ubuntu Services Are Managed with systemd
Introduction
Section titled “Introduction”Modern versions of Ubuntu (from 15.04 onward) use systemd as their init system — the first process that starts when the kernel boots and the parent of all other processes.
systemd replaced Upstart and SysV init to provide a faster, more reliable, and more consistent way of managing services.
This document explains how systemd manages services, focusing on units, service lifecycle, dependencies, and logging.
Units: The Building Blocks of systemd
Section titled “Units: The Building Blocks of systemd”In systemd, everything is a unit. A unit is a configuration file that tells systemd how to manage a resource. Common types include:
- Service units (
.service) – describe background processes like web servers (nginx.service) or databases (mysql.service). - Target units (
.target) – group other units together, similar to the old “runlevels”. - Socket units (
.socket) – define network or IPC sockets systemd listens on, activating services on demand. - Timer units (
.timer) – schedule jobs, similar to cron.
Example service unit file (simplified):
[Unit]Description=NGINX Web ServerAfter=network.target
[Service]ExecStart=/usr/sbin/nginx -g 'daemon off;'ExecReload=/bin/kill -s HUP $MAINPIDExecStop=/bin/kill -s QUIT $MAINPIDRestart=always
[Install]WantedBy=multi-user.targetService Lifecycle
Section titled “Service Lifecycle”systemd provides fine-grained control over starting, stopping, and enabling services:
-
Start/Stop/Restart immediately
Terminal window sudo systemctl start nginxsudo systemctl stop nginxsudo systemctl restart nginx -
Enable/Disable at boot
Terminal window sudo systemctl enable nginx # start automatically on bootsudo systemctl disable nginx # prevent automatic start -
Check status
Terminal window systemctl status nginx
This shows whether the service is active, inactive, or failed, along with recent log output.
Dependencies and Ordering
Section titled “Dependencies and Ordering”Units can depend on each other. For example, a web server may require the network stack before starting. Dependencies are expressed with directives:
-
After=– ensures ordering (start this unit only after another one has started). -
Requires=– makes one unit depend on another; if the required unit fails, so does the dependent one.
Example:
[Unit]Description=My Web AppRequires=network.targetAfter=network.targetThis guarantees the web app won’t attempt to start before networking is available.
Targets: Grouping Units
Section titled “Targets: Grouping Units”Targets are collections of units that represent a desired system state. They replace SysV’s runlevels:
-
multi-user.target→ non-graphical, multi-user environment (servers often boot into this). -
graphical.target→ includes a desktop environment. -
rescue.target→ single-user mode for troubleshooting.
You can switch targets with:
sudo systemctl isolate multi-user.targetLogs and Debugging
Section titled “Logs and Debugging”systemd integrates tightly with journald, a logging system. You can view logs for services or the system:
-
Logs for a specific service:
Terminal window journalctl -u nginx.service -
Show only the latest entries and follow new ones:
Terminal window journalctl -u nginx.service -f -
General system logs:
Terminal window journalctl -b
This unified logging makes troubleshooting easier compared to older init systems.
Conclusion
Section titled “Conclusion”systemd is more than just a replacement for init — it’s a comprehensive service manager that:
-
Provides consistent service lifecycle management.
-
Handles dependencies and ordering automatically.
-
Groups services into logical targets.
-
Centralizes logging for easier debugging.
By understanding how units, targets, and journald work together, you can confidently manage and troubleshoot services on Ubuntu.