Hello! Welcome to your next lesson.
In our last session, you mastered the systemctl command to control services like starting, stopping, and enabling them. We ended with a question: how does systemd actually know how to manage a service like Apache? The answer lies in simple configuration files.
Today's lesson will uncover those configuration files. We'll be addressing the learning outcome: Describe the purpose and basic structure of a systemd unit file. Understanding these files is a crucial step towards mastering system administration, as they are the blueprints systemd uses to manage almost every resource on a modern Linux system.
1. What are Unit Files?
In the previous lesson, we focused on "services." However, systemd is capable of managing much more. It manages resources called units. A service is just one type of unit. Other examples include sockets (.socket), mount points (.mount), and devices (.device).
Each unit is defined by a configuration file called a unit file. This is a plain text file that tells systemd everything it needs to know about a resource: what it is, what its dependencies are, and how to start or stop it.
To get a solid grasp of what unit files are and where they live on the system, the following article provides an excellent introduction.
Understanding Systemd Units and Unit Files
The DigitalOcean tutorial 'Understanding Systemd Units and Unit Files' clearly explains what units are and lists the different directories where unit files are stored, explaining the priority of each location.
Please read the introduction and the first three sections: 'Introduction' 'What do Systemd Units Give You?' 'Where are Systemd Unit Files Found?' 'Types of Units' Focus on understanding the different locations for unit files and why the /etc/systemd/system directory has the highest priority. Also, note the different types of units that exist beyond just .service files.
Key Locations and Priority
As you just read, there are three primary directories for unit files, and systemd reads them in a specific order of priority:
/etc/systemd/system/(Highest Priority): This is where you, as the system administrator, place your own custom unit files or override existing ones. Files here are safe from package updates./run/systemd/system/(Medium Priority): Used for unit files generated at runtime. These are temporary and are lost on reboot./usr/lib/systemd/system/(Lowest Priority): This is where the unit files for software installed via package managers (likeaptoryum) are placed. You should never edit files in this directory directly, as your changes would be overwritten the next time the package is updated.
This priority system is powerful. It allows you to override the default behavior of a service by creating a modified copy in /etc/systemd/system without touching the original package file.
2. The Structure of a Unit File
Now that we know what unit files are and where to find them, let's dissect their structure. A unit file is organized into sections, with each section name enclosed in square brackets (e.g., [Unit]). Within each section, directives are defined in a simple Key=Value format.
For a typical service, you will almost always see these three sections:
[Unit][Service][Install]
The following documentation from Red Hat provides a definitive guide to the structure and the most common options you'll encounter.
Chapter 1. Working with systemd unit files
The Red Hat documentation 'Working with systemd unit files' provides a detailed, technical breakdown of the unit file structure and the key directives within each section.
Read the following four sections to understand the core components of a unit file: 'Unit file structure': This gives a high-level overview of the three main sections. 'Important [Unit] section options': Focus on Description, After, and Wants. 'Important [Service] section options': Pay close attention to Type, ExecStart, and Restart. 'Important [Install] section options': Understand the purpose of WantedBy. This is a dense but excellent reference. Don't worry about memorizing every option; focus on the purpose of each section.
Let's summarize the key directives from that reading.
The [Unit] Section
This section contains generic information about the unit and its relationship with other units.
| Directive | Description |
|---|---|
Description= |
A human-readable description of the unit. This is what you see in the output of systemctl status. |
After= |
Defines the startup order. For example, After=network.target ensures this service only starts after the network is up. |
Wants= |
A "soft" dependency. systemd will try to start the listed units, but the current unit will not fail if they don't start. |
Requires= |
A "hard" dependency. If a unit listed here fails to start, the current unit will also be deactivated. |
The [Service] Section
This section contains configuration specific to how the service should be managed.
| Directive | Description |
|---|---|
Type= |
Specifies the process startup type. Common types are simple (the default), forking (for older daemons), and oneshot (for one-off tasks). |
ExecStart= |
The most important directive. This defines the exact command (with its full path) that will be run to start the service. |
Restart= |
Defines the automatic restart policy. on-failure or always are very common in DevOps to ensure high availability. |
User= / Group= |
Specifies the user and group the service process should run as. A critical security best practice to avoid running services as root. |
ExecReload= |
Specifies the command to execute to reload the service's configuration without a full restart (e.g., sudo systemctl reload nginx). |
The [Install] Section
This section defines what happens when you run systemctl enable or systemctl disable.
| Directive | Description |
|---|---|
WantedBy= |
This tells systemctl enable which target (think of it as a runlevel) this service should be linked to. For most background services, this is multi-user.target, meaning the service should start when the system is ready for multiple users to log in. |
3. A Real-World Example
Let's analyze a complete, simple unit file to see these concepts in action. The following image shows a custom service file created to run an nmap scan periodically.

Let's break it down:
-
[Unit]Section:Description=My custom Nmap service: This is the friendly name that will appear when you runsystemctl status nmapper.service.After=network.target: This service will only start after the system's networking is fully active. This makes sense, as annmapscan requires the network.
-
[Service]Section:Type=simple: This is a standard process that does not fork or do anything complex on startup.User=root: The command will be executed as therootuser.ExecStart=/usr/bin/nmap -sS -p 1-1000 127.0.0.1: This is the core command. When you runsudo systemctl start nmapper.service,systemdwill execute this exactnmapcommand.Restart=always: If thenmapcommand finishes or fails for any reason,systemdwill automatically restart it.RestartSec=30: It will wait 30 seconds before attempting the restart.
-
[Install]Section:WantedBy=multi-user.target: If you runsudo systemctl enable nmapper.service,systemdwill create a symbolic link that effectively hooks this service into the standard boot process.
Test your understanding!
Based on the nmapper.service file above, which of the following statements is false?
- To make this service start on boot, you would run
sudo systemctl enable nmapper.service. - The service will run an
nmapscan against the local machine. - If the network is down, the service will fail to start because of the
Wants=network.targetdirective. - If the service stops for any reason,
systemdwill try to start it again after 30 seconds.
Show answer
Statement 3 is false. The directive is After=network.target, not Wants=network.target. While they are often used together, After= only dictates the order of startup. Wants= or Requires= would create a dependency. In this file, there is no explicit dependency on network.target, only an ordering rule. However, the command itself would likely fail without a network, and because of Restart=always, it would just keep retrying.
Your Turn to Explore
Now, find the unit file for the Apache service you installed in the last lesson on your own system. Its location will be /usr/lib/systemd/system/ and the filename will be either apache2.service (on Debian/Ubuntu) or httpd.service (on CentOS/RHEL).
Use the cat or less command to view its contents:cat /usr/lib/systemd/system/apache2.service
Compare what you see with the concepts we've discussed. You'll likely see more complex directives, but you should be able to identify the main sections and key commands like ExecStart.
Conclusion
You have now demystified how systemd works under the hood. Unit files are the fundamental building blocks for managing resources on a modern Linux system. As a DevOps engineer, you will frequently need to read, understand, and sometimes even write or modify these files to deploy and manage applications reliably.
Key Takeaways:
- A unit file is a text file that describes a resource and tells
systemdhow to manage it. - Unit files from installed packages are in
/usr/lib/systemd/system/; administrator overrides and custom files go in/etc/systemd/system/. - The three key sections are
[Unit](metadata and dependencies),[Service](execution logic), and[Install](enable/disable behavior). - Directives like
ExecStart,Restart,After, andWantedByare the essential instructions that define a service's lifecycle.
This lesson concludes our module on Linux System Administration Essentials. In our next lesson, we will begin a new module, Networking Fundamentals for DevOps, starting with the learning outcome: Explain the OSI model layers and their functions in network communication.