In the world of Linux-based systems, managing services efficiently is crucial for system administrators and developers alike. One of the most prevalent tools for this purpose is systemd, a system and service manager that has become the default init system for many popular Linux distributions. In this article, we’ll explore what systemd services are, how they work, and the different types of services supported by systemd.
What is systemd?
Systemd is a system and service manager for Linux operating systems. It is designed to start, stop, and manage system services and resources during boot and throughout the system’s runtime. Some key features of systemd include:
- Service Management: It provides a way to define and manage services (also called units) using unit files, which specify how services should behave.
- Parallel Startup: Systemd can start services in parallel during boot, which can significantly reduce boot times.
- Dependency Management: It manages dependencies between services, ensuring that they start in the correct order.
- Logging: It includes a logging component called the journal, which collects and manages log messages from the system and services.
- Socket Activation: Systemd can start services on-demand when they receive network requests, helping to conserve resources.
- Timer Units: It can replace cron jobs with timer units, allowing for scheduled tasks to be managed more easily.
Systemd has become the default init system for many major Linux distributions, including Fedora, Ubuntu, and CentOS, due to its efficiency and powerful features.
What is a systemd service?
A systemd service is a unit configuration file that defines how a specific service should be started, stopped, and managed by the systemd system and service manager. These files typically have a .service extension and reside in directories such as /etc/systemd/system/ or /lib/systemd/system/.
Types of systemd Units
systemd organizes its management of services into different unit types. The most common types include:
Service Units (.service): These units define how to start, stop, and manage a service. They are the backbone of most systemd operations.
Example: A simple web server service might look like this:
[Unit]
Description=Simple Web Server
[Service]
ExecStart=/usr/bin/python3 -m http.server
Restart=on-failure
[Install]
WantedBy=multi-user.target
Socket Units (.socket): These units manage inter-process communication through sockets. They allow services to be started on-demand when a connection is made to a specified socket.
Example: A socket unit for the web server could be:
[Unit]
Description=Socket for Simple Web Server
[Socket]
ListenStream=8080
Accept = yes
[Install]
WantedBy=sockets.target
Target Units (.target): These act as synchronization points for services. They group multiple services together for starting or stopping.
Example: A target for graphical services might look like:
[Unit]
Description=Graphical Interface
[Install]
WantedBy=multi-user.target
Timer Units (.timer): These units are used to schedule services to run at specific intervals or times, similar to cron jobs.
Example: A timer to run a backup service every day could be defined as follows:
[Unit]
Description=Daily Backup Timer
[Timer]
OnCalendar=daily
[Install]
WantedBy=timers.target
Mount Units (.mount):These units manage filesystem mounts. Each mount point in the system can have a corresponding mount unit.
Example: A mount unit for a directory might look like this:
[Unit]
Description=Mount Example Directory
[Mount]
What=/dev/sda1
Where=/mnt/example
Type=ext4
[Install]
WantedBy=multi-user.target
Automount Units (.automount): These units are used for automatically mounting filesystems on access.
How to Manage systemd Services
Managing systemd services involves using the systemctl command.
Basic systemctl commands
Here are some common commands that you can use to start/stop , restart : enable/disable and print status , logs of services.
sudo systemctl start <service_name>.service
sudo systemctl stop <service_name>.service
sudo systemctl restart <service_name>.service
sudo systemctl enable <service_name>.service
sudo systemctl disable <service_name>.service
systemctl status <service_name>.service
journalctl -u <service_name>.service
Note : By default, most systemd services are not started automatically at boot. To configure this functionality, you need to “enable” them.
Create a Custom systemd Service
Basic simple service
target script
we will start/execute t.sh which is a fish script using the system service
# lets write a simple scritp which start this t.sh script
cat t.sh
#!/bin/fish
while true
echo "hello world"
sleep 2
end
Simple service
Simple service runs continuously in the foreground and is expected to stay active.
example-1
# Let’s create a file called with the following content
/etc/systemd/system/test.service
[Unit]
Description=demo service
After=network.target
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=1
User=bt
ExecStart=/usr/bin/fish /home/bt/test.sh
[Install]
WantedBy=multi-user.target
Explanation
- Description — This provides a brief description of the service. It’s mainly for informational purposes and can be seen when querying the service status.
- After=network.target — This specifies that the service should start only after the network.target has been reached. This ensures that network-related services are available before this service starts.
- StartLimitIntervalSec=0 — This directive defines the time frame in which a limit on the number of restarts applies. Setting it to 0 means there is no limit; the service can restart indefinitely without restrictions.
- Type=simple — This indicates that the service will be considered started immediately after the ExecStart command is executed. This is typical for scripts or applications that run in the foreground.
- Restart=always — This tells systemd to always restart the service if it exits for any reason, whether it fails or stops. This ensures high availability of the service.
- RestartSec=1 — This sets a delay of 1 second before attempting to restart the service after it has stopped. This prevents rapid cycling in case of persistent failures.
- User=bt — This specifies that the service should run under the bt user account. This is important for managing permissions and ensuring that the service has the appropriate access rights.
- ExecStart=/usr/bin/fish test.sh –This is the command that systemd will execute to start the service. Here, it runs the Fish shell with the script test.sh. This is the main action of the service.
- WantedBy=multi-user.target — This specifies that the service should be started when the system reaches the multi-user.target, which is a common target for systems running multiple user sessions. It essentially enables the service to start during system boot at the appropriate runlevel.
Note: By default, when you configure Restart=always as we did, systemd gives up restarting your service if it fails to start more than 5 times within a 10 seconds interval. This behaviour is controlled by :
- StartLimitBurst=5
- StartLimitIntervalSec=10
It helps to prevent a service from entering a rapid restart loop, which could overwhelm the system resources or indicate a deeper issue with the service. If the number of restarts exceeds this limit within the defined interval, systemd will stop attempting to restart the service. But for running simple bash / python scripts this behaviour should be avoided by using RestartSec.
example-2
[Unit]
Description=My Python tiny script
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/python3 /root/python-tiny/tiny.py 2 1
ExecStop=/usr/bin/python3 /root/python-tiny/tinyT.py 2 0
Restart=no
[Install]
WantedBy=multi-user.target
Explanation
- ExecStop — This is executed when the service is stopped. This can occur in several scenarios:
- Manual Stop: If you manually stop the service using a command like sudo systemctl stop service_name, systemd will run the command specified in ExecStop to perform any necessary cleanup or shutdown tasks.
- System Shutdown: During a system shutdown or reboot, systemd will stop all active services. For services with an ExecStop defined, it will execute that command as part of the shutdown process.
- Service Restart: If the service is restarted (manually or due to configuration changes), systemd will first run the ExecStop command to stop the existing service instance before starting a new one.
- Restart=no — This indicates that the service should not be automatically restarted if it exits or fails. This is useful for one-off scripts where you don’t want to keep trying to relaunch them if they terminate unexpectedly.
Oneshot service
A oneshot service in systemd is designed for short-lived tasks that run to completion and then exit. This is different from a simple service, which is intended for long-running processes that do not exit. Oneshot service is often used for tasks that need to be performed once at boot or during system operation, such as initialization scripts or configuration tasks.
example-1
[Unit]
Description=Update System Packages
[Service]
Type=oneshot
WorkingDirectory=/home/bt
ExecStart=/usr/bin/fish ntest.sh
TimeoutStartSec=0
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Explanation
- TimeoutStartSec — When you set TimeoutStartSec=0, it effectively disables the timeout for starting the service. This means that systemd will wait indefinitely for the service to start without imposing any time limit.This setting is useful for services that may take an unusually long time to start. For example, if a service needs to initialize a large database or connect to a remote server that might have unpredictable response times, disabling the timeout can prevent premature failure.
- RemainAfterExit=yes — Keeps the service active in a “successful” state after it has completed its task, allowing you to check its status.
- WorkingDirectory=/home/bt — It specifies the directory from which the service should be executed. in this case ntest.sh resides in “/home/bt” so we do not have to write the absolute path in ExecStart.
example-2
[Unit]
Description=Oneshot service test with ExecStop and RemainAfterExit
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/bash -c "echo Oneshot service - start && sleep 60 && echo Oneshot service - end"
ExecStop=/bin/bash -c "echo Oneshot service - stop"
Explanation
- Without RemainAfterExit=yes, the ExecStop command will run immediately after ExecStart completes.
- To execute ExecStop, you must stop the service using systemctl stop your-service or restart or shutdown the system.This is a great way to effectively run something at shutdown
example-3
A simple service can only include one ExecStart directive. In contrast, a oneshot service can have zero, one, or multiple ExecStart commands. If there is no ExecStart, you must define ExecStop and set RemainAfterExit. This configuration would create a service that runs only on shutdown, resembling oneshot-execstop-remainafterexit-install.service but without the ExecStart directive.
[Unit]
Description=Oneshot service test with multiple ExecStart
[Service]
Type=oneshot
ExecStart=/bin/bash -c "echo First"
ExecStart=/bin/bash -c "echo Second"
ExecStart=/bin/bash -c "echo Third"
To start/stop/restart , enable/disable , print the status and log of this service we will use
# After createing / modifying the servie file you will need to reload the systemd manager configuration
# without this you will have to restart the system
sudo systemctl daemon-reload
# After reloading you can perform start , stop etc operation
sudo systemctl start test
sudo systemctl stop test
sudo systemctl restart test
sudo systemctl status test
sudo systemctl enable test
sudo systemctl disable test
journalctl -u test.service
# start + enable with single command
systemctl enable --now test-app.service
# STart/Enables the service only for the current user
systemctl --user daemon-reload
systemctl --user is-enabled SERVICE-NAME.service
systemctl --user enable scoreboard.service
systemctl --user start scoreboard.service
Advanced systemctl
# To list all loaded services on your system (whether active; running, exited, or failed
systemctl --type=service
# list all loaded but active services, both running and those that have exited
systemctl --type=service --state=active
# list only running services
systemctl --type=service --state=running
# list only exited services
systemctl --type=service --state=exited
# list failed services
systemctl --type=service --state=failed
# list the dependencise of service
systemctl list-dependencies --all nginx.service
# list low-level details of the unit’s settings on the system
systemctl show nginx.service
# inspect unint file of a service
systemctl cat nginx.service
# edit the unit file of a service
systemctl edit nginx.service
systemctl edit --full nginx.service
# To print what units are tied to a target,
systemctl list-dependencies multi-user.target
# change the target
systemctl set-default multi-user.target
# To switch to specific target
systemctl isolate multi-user.target
journalctl
journalctl is a command-line utility for querying and displaying logs from the systemd journal, which is a component of systemd that collects and manages log messages from various sources, including the kernel, system services, and user applications.
Key Uses of journalctl:
- Log Viewing: It allows you to view log entries in a structured and organized manner.
- Filtering Logs: You can filter logs by time, service, priority, and other criteria.
- Persistent Logging: It can store logs in a persistent manner across reboots, depending on the system configuration.
- Real-Time Monitoring: It supports real-time monitoring of logs
Basic usage
# view all the logs
journalctl
# View Logs for a Specific Service:
journalctl -u your-service-name
# View Logs from the Current Boot
journalctl -b
# Follow Logs in Real-Time
journalctl -f
# View Logs for a Specific Time Period:
journalctl --since "2024-10-28" --until "2024-10-29"
# View Logs with Specific Priority:
journalctl -p warning
# Export Logs to a File
journalctl > logs.txt
# combine -u and -b
journalctl -b -u nginx.service
Conclusion
systemd provides a powerful and flexible way to manage services in Linux environments. With various unit types, it enables intricate configurations and ensures efficient resource management. Understanding how to leverage systemd services will not only streamline your system management tasks but also enhance your overall productivity as a system administrator or developer. Whether you’re setting up a simple service or managing a complex application stack, mastering systemd is an invaluable skill in today’s tech landscape.