How to Manage Systemd Services and Units on RHEL 7
Red Hat Enterprise Linux 7 made a significant shift from the traditional SysVinit and Upstart initialization systems to systemd as the default init system. Systemd is a comprehensive system and service manager that controls how services start, stop, and interact with the rest of the operating system. Understanding how to work with systemd is essential for any RHEL 7 administrator, whether you are managing web servers, databases, or custom application services. This tutorial walks you through the core systemctl commands, unit file structure, creating your own service units, and using journalctl to inspect service logs.
Prerequisites
- A running RHEL 7 system (physical, virtual machine, or cloud instance)
- A user account with
sudoprivileges or direct root access - Basic familiarity with the Linux command line and a text editor such as
viornano
Step 1: Understanding Systemd Units
In systemd, every managed resource is called a unit. Units are described by unit files and come in several types identified by their file extension. The most common type is the .service unit, which describes a daemon or background process. Other types include .socket, .target, .mount, .timer, and more.
Unit files are searched in the following locations, in order of priority:
/etc/systemd/system/— administrator-defined units (highest priority)/run/systemd/system/— runtime units generated by the system/usr/lib/systemd/system/— units installed by RPM packages (do not edit these directly)
To list all loaded units currently known to systemd, use:
systemctl list-units
To restrict the listing to service units only:
systemctl list-units --type=service
To see all installed unit files regardless of their active state:
systemctl list-unit-files --type=service
Step 2: Checking Service Status
Before modifying any service, it is good practice to check its current state. The status subcommand provides a concise summary including whether the service is active, its PID, recent log entries, and whether it is enabled to start at boot.
sudo systemctl status sshd
Example output:
● sshd.service - OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2026-05-17 09:00:00 EDT; 2h 15min ago
Main PID: 1245 (sshd)
CGroup: /system.slice/sshd.service
└─1245 /usr/sbin/sshd -D
May 17 09:00:00 hostname systemd[1]: Started OpenSSH server daemon.
The Loaded line shows whether the unit is enabled (starts at boot) or disabled. The Active line shows the current runtime state.
Step 3: Starting, Stopping, and Restarting Services
The most common day-to-day operations are starting and stopping services. These commands affect the currently running state but do not change whether the service starts automatically at boot.
# Start a service
sudo systemctl start httpd
# Stop a service
sudo systemctl stop httpd
# Restart a service (stop then start)
sudo systemctl restart httpd
# Reload configuration without restarting (if the service supports it)
sudo systemctl reload httpd
# Reload or restart — use reload if available, fall back to restart
sudo systemctl reload-or-restart httpd
Use restart when you need to apply changes that require the process to fully reinitialize. Use reload for lighter changes such as updating configuration files in services like nginx or Apache that support live reloading.
Step 4: Enabling and Disabling Services at Boot
Enabling a service creates a symlink so that systemd starts it automatically during the appropriate boot target. Disabling removes that symlink.
# Enable a service to start at boot
sudo systemctl enable httpd
# Disable a service from starting at boot
sudo systemctl disable httpd
# Enable and immediately start a service in one command
sudo systemctl enable --now httpd
# Disable and immediately stop a service in one command
sudo systemctl disable --now httpd
To check whether a service is currently enabled:
systemctl is-enabled httpd
To check whether a service is currently running:
systemctl is-active httpd
Step 5: Creating a Custom Service Unit File
One of the most powerful features of systemd is the ability to create your own service units for custom applications. Suppose you have a Python web application located at /opt/myapp/app.py that you want managed as a system service.
Create the unit file at /etc/systemd/system/myapp.service:
sudo vi /etc/systemd/system/myapp.service
Paste the following content:
[Unit]
Description=My Custom Python Web Application
After=network.target
[Service]
Type=simple
User=myappuser
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/python3 /opt/myapp/app.py
Restart=on-failure
RestartSec=5s
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
The key sections are:
- [Unit] — metadata and ordering dependencies.
After=network.targetensures the service starts after networking is available. - [Service] — defines the process, user context, restart behavior, and how output is handled.
- [Install] — defines when this service should be started.
WantedBy=multi-user.targetmeans it starts in normal multi-user mode (equivalent to runlevel 3).
After creating or modifying any unit file in /etc/systemd/system/, you must reload the systemd daemon so it recognizes the changes:
sudo systemctl daemon-reload
Then enable and start your service:
sudo systemctl enable --now myapp.service
sudo systemctl status myapp.service
Step 6: Viewing Service Logs with journalctl
Systemd captures all service output (stdout and stderr) into the systemd journal. The journalctl command is used to query it.
# View all logs for a specific service
sudo journalctl -u sshd
# Follow logs in real time (like tail -f)
sudo journalctl -u sshd -f
# Show only the last 50 lines
sudo journalctl -u sshd -n 50
# Show logs since a specific time
sudo journalctl -u sshd --since "2026-05-17 09:00:00"
# Show logs from the current boot only
sudo journalctl -u sshd -b
# Show logs with priority error and above
sudo journalctl -u sshd -p err
The journal is stored in a binary format and provides fast filtering by unit, time range, priority, and other criteria. For persistent journal storage across reboots, ensure /var/log/journal/ exists:
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald
Step 7: Masking and Unmasking Services
Sometimes you need to prevent a service from being started — even manually — by another service or administrator. Masking a service creates a symlink to /dev/null, making it impossible to start until it is unmasked.
# Mask a service (prevent it from ever starting)
sudo systemctl mask postfix
# Unmask a service (restore the ability to start it)
sudo systemctl unmask postfix
This is useful when you have conflicting services (e.g., two mail transfer agents installed) and you need to ensure only one can ever run.
Step 8: Inspecting Unit File Contents
To view the full contents of a unit file as systemd sees it (including any drop-in overrides):
systemctl cat sshd.service
To view only the properties of a unit at runtime:
systemctl show sshd.service
To check all unit files for syntax errors after making edits:
sudo systemd-analyze verify /etc/systemd/system/myapp.service
Conclusion
Systemd is the backbone of service management on RHEL 7 and mastering it gives you precise control over every aspect of your system’s runtime behavior. You have learned how to check service status, start and stop services, enable them at boot, create custom unit files, and query logs through journalctl. The ability to write your own service units is particularly valuable when deploying applications that do not come with built-in package management support. As you grow more comfortable with systemd, explore advanced features such as .timer units for scheduled tasks (replacing cron), dependency ordering with Wants= and Requires=, and resource limits via the LimitNOFILE and MemoryMax directives in your [Service] sections.