How to add customizations to a service unit or override the unit without modifying the original

Solution Verified - Updated

Environment

  • Red Hat Enterprise Linux (RHEL) 7
  • Red Hat Enterprise Linux (RHEL) 8

Issue

  • I want to add additional entries to a service unit's After= line without overriding the entire existing line.
  • I want to replace a service unit with my own customized version.

Resolution

The following information is provided as an example and does not guarantee every situation. Red Hat support can assist with questions about unit file configurations and syntax, but does not create, provide, or support custom systemd service unit files as they fall under 3rd party and code development, and are therefore not covered by Red Hat's support scope.

All Red Hat maintained packages for Red Hat Enterprise Linux 7 and 8 will be installed with systemd already working. Customized service files are not covered by Red Hat's scope of support. Additionally, any third party who provides software certified to run on Red Hat Enterprise Linux 7 or 8 should already include a systemd unit file created for Red Hat Enerprise Linux 7 or 8. Do not attempt to add customizations to any third party service files before speaking with the third-party software provider and asking for a relevant unit file.

  • In order to add entries to a service unit's existing properties, such as After=, the systemctl edit command can be used. There are two ways to use this command:
systemctl edit servicename.service
systemctl edit --full servicename.service
  • The first method, systemctl edit servicename.service is the one we want to use. In the example below, we will be adding mariadb.service to the After= line, so that httpd.service doesn't start until after mariadb.service has started:
# systemctl edit httpd.service

This will create a blank file named override.conf in the path /etc/systemd/system/httpd.service.d/ which you will have to add your customization to and save. In our example we're simply going to add:

[Unit]
After=mariadb.service

Then save and close the file. Note that you must include the correct section of the service you want the override in. In our case, [Unit] is the section the After= option is in. Now, After=mariadb.service will be appended to the file when it starts. We can also run systemctl status httpd.service and see the override.conf being used:

# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/httpd.service.d
           └─override.conf                                               <===============Here's our override.
  • Alternatively, if we want to override the entire service file, we can use the second method, systemctl edit --full servicename.service. In the next example, we will modify the httpd.service and manually add After=mariadb.service to the existing unit file:
# systemctl edit --full httpd.service

This command makes a copy of the original service unit located at /usr/lib/systemd/system/httpd.service and places the copy at /etc/systemd/system/httpd.service. This prevents the original from being modified, and also overrides any pre-existing symlinks for enabled services found in any of the targets within /etc/systemd/system/, such as /etc/systemd/system/multi-user.target.wants/httpd.service. The command will then open the copy so that you can make your changes. We have modified ours with the After=mariadb.service entry:

[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
After=mariadb.service
Documentation=man:httpd(8)
Documentation=man:apachectl(8)

[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/httpd
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
ExecStop=/bin/kill -WINCH ${MAINPID}
KillSignal=SIGCONT
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Now, if we restart the service and run systemctl status httpd we can see the customized unit being used instead of the original:

# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/etc/systemd/system/httpd.service; enabled; vendor preset: disabled)   <======= Here's our custom unit path.
  • Note: If you have both a custom systemd unit, and a custom override, the custom unit will use the override:
# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/etc/systemd/system/httpd.service; enabled; vendor preset: disabled)   <======= Here's our custom unit path.
  Drop-In: /etc/systemd/system/httpd.service.d
           └─override.conf                                               <===============Here's our override.
SBR
Components
Tags

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.