Linux and Bash course menu
systemd and systemctl Tutorial: Manage Linux Services and Logs
Start, stop and enable services with systemctl, read logs with journalctl, and write your own systemd service file so that an app runs at boot and restarts on failure.
On this page
A service is a program that runs in the background, such as a web server or database. On most Linux systems, services are managed by systemd, using the systemctl command.
Check a service#
systemctl is-active cron
systemctl status cron --no-pager | head -n 3 | cut -c1-74active
● cron.service - Regular background program processing daemon
Loaded: loaded (/usr/lib/systemd/system/cron.service; enabled; preset
Active: active (running) since Thu 2026-11-05 06:22:12 UTC; 4min 22sactive (running) means that it is working, and enabled means that it starts at boot.
Control a service#
sudo systemctl start nginx # start now
sudo systemctl stop nginx # stop now
sudo systemctl restart nginx # stop and start
sudo systemctl reload nginx # reload settings, no downtime
sudo systemctl enable nginx # start at every boot
sudo systemctl disable nginx # do not start at bootstart and enable are different. A service can run now and not start at the next boot, and the other way round. sudo systemctl enable --now nginx does both.
List services#
systemctl list-units --type=service --state=running --no-pager --no-legend | wc -l
systemctl list-units --type=service --state=failed --no-pager --no-legend | wc -l26
0Create your own service#
We will make a small program into a real service. First, the program, a script that writes a line every second:
sudo tee /usr/local/bin/heartbeat.sh > /dev/null <<'EOF'
#!/bin/bash
while true; do
echo "Heartbeat at $(date +%T)"
sleep 1
done
EOF
sudo chmod +x /usr/local/bin/heartbeat.shNext, the unit file, which tells systemd how to run it:
sudo tee /etc/systemd/system/heartbeat.service > /dev/null <<'EOF'
[Unit]
Description=Heartbeat demo
After=network.target
[Service]
ExecStart=/usr/local/bin/heartbeat.sh
Restart=on-failure
User=asha
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now heartbeat 2> /dev/null
sleep 2
systemctl is-active heartbeat
systemctl is-enabled heartbeatactive
enableddaemon-reload is needed each time you change a unit file.
This is how you run a Node.js or Python app on a server: ExecStart=/usr/bin/node /srv/app/server.js.
Read the logs#
Everything a service prints is collected in the journal, and read with journalctl:
sudo journalctl -u heartbeat -n 2 --no-pager -o catHeartbeat at 06:26:36
Heartbeat at 06:26:37Traditional log files#
Many programs also write to /var/log:
Stop and clean up#
sudo systemctl disable --now heartbeat 2> /dev/null
systemctl is-active heartbeat
sudo rm /etc/systemd/system/heartbeat.service /usr/local/bin/heartbeat.sh
sudo systemctl daemon-reloadinactiveWhen a service fails#
- Run
systemctl status name, and read the last lines. - Run
journalctl -u name -n 50. - Run the
ExecStartcommand by hand, as the same user. - Check paths, permissions, and whether the port is already in use.
Common mistakes#
Practice#
Practice exercise
Print the status word for cron and ssh, then print the description of cron using systemctl show.
Show solution
systemctl is-active cron ssh
systemctl show cron -p Descriptionactive
active
Description=Regular background program processing daemonKey takeaway#
Next: Installing Software with apt.
Finished this lesson?