systemd and Services
systemd and Services#
Concepts#
What Is an Init System?#
When Linux boots, the kernel starts a single process: PID 1, the init system. This process is responsible for starting everything else: services, login screens, network interfaces, and more.
On both Ubuntu 24.04 and Debian 12, the init system is systemd. It replaced older init systems (SysVinit, Upstart) and is now the standard on most Linux distributions.
systemd does more than just start services. It manages:
- Services (daemons): background processes like web servers, SSH, databases
- Targets (runlevels): system states like multi-user, graphical, rescue
- Timers: scheduled tasks (alternative to cron)
- Mounts: filesystem mounting
- Sockets: network socket activation
- Logging: the journal (
journalctlwhich will be discussed in the next lesson)
Units#
Everything systemd manages is a unit. Each unit is defined by a unit file — a configuration file that describes what to start and how.
| Unit Type | Extension | Purpose |
|---|---|---|
| Service | .service |
A daemon or one-shot process |
| Target | .target |
A group of units (like a runlevel) |
| Timer | .timer |
Scheduled activation |
| Socket | .socket |
Network/IPC socket |
| Mount | .mount |
Filesystem mount point |
| Device | .device |
Hardware device |
| Path | .path |
File/directory watcher |
systemctl — The Main Command#
systemctl is how you interact with systemd.
Managing Services#
# Check status of a service
systemctl status ssh
systemctl status nginx
# Start a service (runs it now)
sudo systemctl start nginx
# Stop a service
sudo systemctl stop nginx
# Restart (stop + start)
sudo systemctl restart nginx
# Reload configuration without full restart (if supported)
sudo systemctl reload nginx
# Restart only if already running
sudo systemctl try-restart nginx
# Enable a service (start automatically at boot)
sudo systemctl enable nginx
# Disable (do not start at boot)
sudo systemctl disable nginx
# Enable AND start immediately
sudo systemctl enable --now nginx
# Check if a service is enabled
systemctl is-enabled nginx
# Check if a service is active (running)
systemctl is-active nginx
Listing Units#
# List all active services
systemctl list-units --type=service
# List all services (including inactive)
systemctl list-units --type=service --all
# List enabled/disabled services
systemctl list-unit-files --type=service
# List failed services
systemctl --failed
Reading systemctl status#
systemctl status ssh
● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/usr/lib/systemd/system/ssh.service; enabled; preset: enabled)
Active: active (running) since Mon 2024-10-15 08:00:00 UTC; 2h ago
Docs: man:sshd(8)
Main PID: 456 (sshd)
Tasks: 1 (limit: 4681)
Memory: 3.2M
CPU: 120ms
CGroup: /system.slice/ssh.service
└─456 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
Key fields:
- Loaded: Path to unit file, whether it is enabled
- Active: Current state and how long it has been in that state
- Main PID: The primary process
- Tasks/Memory/CPU: Resource usage
- CGroup: Control group hierarchy
- Recent log entries appear below
Unit Files#
Unit files are stored in specific locations:
| Location | Purpose |
|---|---|
/usr/lib/systemd/system/ |
Installed by packages — do not edit directly |
/etc/systemd/system/ |
Admin overrides and custom units (highest priority) |
/run/systemd/system/ |
Runtime units (temporary) |
To view a unit file:
systemctl cat ssh.service
Basic structure of a service unit file:
[Unit]
Description=My Service
After=network.target
Wants=network.target
[Service]
Type=simple
ExecStart=/usr/bin/myprogram --config /etc/myprogram.conf
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5
User=myuser
Group=mygroup
[Install]
WantedBy=multi-user.target
| Section | Field | Meaning |
|---|---|---|
[Unit] |
Description |
Human-readable name |
After |
Start after these units | |
Wants |
Weak dependency — prefer to start these, but OK if they fail | |
Requires |
Hard dependency — fail if these cannot start | |
[Service] |
Type |
simple (default), forking, oneshot, notify |
ExecStart |
Command to start the service | |
ExecReload |
Command to reload config | |
Restart |
When to auto-restart: no, on-failure, always |
|
User/Group |
Run as this user/group | |
[Install] |
WantedBy |
Which target enables this service |
Overriding Unit Files#
Never edit files in /usr/lib/systemd/system/ — they will be overwritten by package updates. Instead, use drop-in overrides:
sudo systemctl edit nginx.service
# This creates /etc/systemd/system/nginx.service.d/override.conf
# Add only the settings you want to change
# After editing, reload the daemon
sudo systemctl daemon-reload
Targets (Runlevels)#
Targets are groups of units representing system states:
| Target | SysVinit Equivalent | Description |
|---|---|---|
poweroff.target |
0 | Shut down |
rescue.target |
1 | Single-user / rescue mode |
multi-user.target |
3 | Multi-user, no GUI |
graphical.target |
5 | Multi-user with GUI (default desktop) |
reboot.target |
6 | Reboot |
# See current default target
systemctl get-default
# Change default target (e.g., boot to text mode)
sudo systemctl set-default multi-user.target
# Switch target immediately
sudo systemctl isolate multi-user.target # switch to text mode now
sudo systemctl isolate graphical.target # switch to GUI now
Power Management#
sudo systemctl poweroff # shutdown
sudo systemctl reboot # reboot
sudo systemctl suspend # suspend (sleep)
sudo systemctl hibernate # hibernate (if supported)
Lab#
Exercise 1: Explore System Services#
# List all active services
systemctl list-units --type=service | head -20
# Count active services
systemctl list-units --type=service --no-legend | wc -l
# Check for failed services
systemctl --failed
# Check the default target
systemctl get-default
Exercise 2: Inspect a Service#
# Check SSH status
systemctl status ssh
# Is it enabled?
systemctl is-enabled ssh
# Is it running?
systemctl is-active ssh
# View its unit file
systemctl cat ssh.service
# See its dependencies
systemctl list-dependencies ssh.service
Exercise 3: Start and Stop a Service#
# Install a simple service to practice with
sudo apt install -y nginx
# Check status
systemctl status nginx
# Stop it
sudo systemctl stop nginx
systemctl is-active nginx
# inactive
# Start it
sudo systemctl start nginx
systemctl is-active nginx
# active
# Restart
sudo systemctl restart nginx
systemctl status nginx
Exercise 4: Enable and Disable#
# Check if nginx is enabled
systemctl is-enabled nginx
# Disable it (won't start at boot)
sudo systemctl disable nginx
systemctl is-enabled nginx
# disabled
# Enable it again
sudo systemctl enable nginx
systemctl is-enabled nginx
# enabled
# You can also stop and disable in one command
sudo systemctl disable --now nginx
systemctl status nginx
# disabled and stopped
# Re-enable and start
sudo systemctl enable --now nginx
Exercise 5: View Unit Files#
# List where unit files are stored
ls /usr/lib/systemd/system/*.service | head -10
ls /etc/systemd/system/ | head -10
# View a unit file
systemctl cat nginx.service
# See overrides (if any)
systemctl show nginx.service | grep -i fragment
Exercise 6: Clean Up#
# Remove nginx if you don't need it
sudo systemctl disable --now nginx
sudo apt purge -y nginx nginx-common
sudo apt autoremove -y
Review#
1. What is systemd?
systemd is the init system (PID 1) on both Ubuntu 24.04 and Debian 12. It starts and manages services, handles system targets (runlevels), manages logging, and controls many other aspects of the system.
2. What is the difference between `start` and `enable`?
start runs the service right now. enable configures the service to start automatically at boot. They are independent — a service can be started but not enabled (running now but won’t auto-start), or enabled but not started (will start on next boot). Use enable --now to do both.
3. What is the difference between `restart` and `reload`?
restart stops and starts the service (brief downtime). reload asks the service to re-read its configuration without stopping (no downtime). Not all services support reload.
4. Where should you put custom unit files or overrides?
In /etc/systemd/system/ for custom units, or use systemctl edit service.service to create a drop-in override in /etc/systemd/system/service.service.d/. Never edit files in /usr/lib/systemd/system/ — they are managed by packages and will be overwritten on updates.
5. What command reloads systemd after editing a unit file?
sudo systemctl daemon-reload — this tells systemd to re-read all unit files and pick up your changes.
6. What is a target?
A target is a unit that groups other units together, representing a system state. For example, graphical.target means “everything needed for a graphical desktop” and multi-user.target means “everything needed for multi-user text mode.”
7. How do you find failed services?
systemctl --failed lists all units in a failed state. systemctl status service-name shows detailed status and recent log entries for a specific service.
Previous: Signals | Next: Logs and journalctl