systemd Units
Everything systemd manages is a unit. Services, mount points, timers, sockets — they all share the same declarative file format. Once you understand unit files, you can manage virtually any aspect of your system's initialization.
Unit Types
| Extension | Type | What it does |
|---|---|---|
| .service | Service | Manages a daemon/program |
| .target | Target | Groups units, like a milestone |
| .socket | Socket | Manages a socket for socket activation |
| .timer | Timer | Triggers a service on a schedule (cron replacement) |
| .mount | Mount | Manages a filesystem mount point |
| .path | Path | Watches files/dirs, triggers service on change |
| .device | Device | Represents a kernel device |
Service Unit File Anatomy
# /etc/systemd/system/myapp.service
[Unit]
Description=My Application
Documentation=https://example.com/docs
After=network.target postgresql.service
Requires=postgresql.service
[Service]
Type=simple
User=myapp
Group=myapp
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/bin/myapp --config /etc/myapp.conf
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5s
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
Key sections:
- [Unit] — Description, documentation, dependencies
- [Service] — How to start/stop/reload the program
- [Install] — Which target enables this unit
Dependency Keywords
| Keyword | Meaning |
|---|---|
Requires= | Hard dependency — if required unit fails, this unit fails too |
Wants= | Soft dependency — start it if possible, but don't fail if it doesn't |
After= | Ordering — start only after this unit is active |
Before= | Ordering — start before this unit |
BindsTo= | Like Requires, but also stops this unit if required stops |
Conflicts= | Cannot run at same time as this unit |
Timer Units — Replacing Cron
# /etc/systemd/system/backup.timer
[Unit]
Description=Run backup daily
[Timer]
OnCalendar=daily
Persistent=true # run if missed while system was off
Unit=backup.service
[Install]
WantedBy=timers.target
# /etc/systemd/system/backup.service
[Unit]
Description=Backup job
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
# Manage timers
systemctl enable --now backup.timer
systemctl list-timers # show all timers + next trigger time
After Editing Unit Files
# Always reload daemon after editing unit files
sudo systemctl daemon-reload
# View logs for a service
journalctl -u myapp.service -f # follow
journalctl -u myapp.service --since "1 hour ago"