How to modify systemd service configuration

Modify systemd service configuration by using drop-in files, which is useful for automation when using ansible or any other provisioning, configuration management and deployment utility.

I will use redis-server service as an example to modify service limits.

$ sudo systemctl status redis
● redis-server.service - Advanced key-value store
   Loaded: loaded (/etc/systemd/system/redis-server.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2019-09-17 17:24:12 GMT; 28min ago
     Docs: http://redis.io/documentation,
           man:redis-server(1)
 Main PID: 4045 (redis-server)
    Tasks: 4 (limit: 393)
   Memory: 2.1M
   CGroup: /system.slice/redis-server.service
           └─4045 /usr/bin/redis-server 127.0.0.1:6379

Sep 17 17:24:11 buster systemd[1]: Starting Advanced key-value store...
Sep 17 17:24:12 buster systemd[1]: Started Advanced key-value store.

Display default service limits.

$ sudo systemctl show  redis-server | grep ^Limit
LimitCPU=infinity
LimitCPUSoft=infinity
LimitFSIZE=infinity
LimitFSIZESoft=infinity
LimitDATA=infinity
LimitDATASoft=infinity
LimitSTACK=infinity
LimitSTACKSoft=8388608
LimitCORE=infinity
LimitCORESoft=0
LimitRSS=infinity
LimitRSSSoft=infinity
LimitNOFILE=65535
LimitNOFILESoft=65535
LimitAS=infinity
LimitASSoft=infinity
LimitNPROC=1312
LimitNPROCSoft=1312
LimitMEMLOCK=65536
LimitMEMLOCKSoft=65536
LimitLOCKS=infinity
LimitLOCKSSoft=infinity
LimitSIGPENDING=1312
LimitSIGPENDINGSoft=1312
LimitMSGQUEUE=819200
LimitMSGQUEUESoft=819200
LimitNICE=0
LimitNICESoft=0
LimitRTPRIO=0
LimitRTPRIOSoft=0
LimitRTTIME=infinity
LimitRTTIMESoft=infinity

Create service directory with .d/ suffix that will contain drop-in configuration files with .conf suffix used to alter default settings.

$ sudo mkdir /etc/systemd/system/redis-server.service.d

Define NOFILE limit.

$ cat <<EOF | sudo tee /etc/systemd/system/redis-server.service.d/limit_nofile.conf
[Service]
LimitNOFILE=98304
EOF

Define CORE limit.

$ cat <<EOF | sudo tee /etc/systemd/system/redis-server.service.d/limit_core.conf
[Service]
LimitCORE=0
EOF

Reload systemd manager configuration.

$ sudo systemctl daemon-reload

Display updated service limits.

$ sudo systemctl show redis-server | grep ^Limit
LimitCPU=infinity
LimitCPUSoft=infinity
LimitFSIZE=infinity
LimitFSIZESoft=infinity
LimitDATA=infinity
LimitDATASoft=infinity
LimitSTACK=infinity
LimitSTACKSoft=8388608
LimitCORE=0
LimitCORESoft=0
LimitRSS=infinity
LimitRSSSoft=infinity
LimitNOFILE=98304
LimitNOFILESoft=98304
LimitAS=infinity
LimitASSoft=infinity
LimitNPROC=1312
LimitNPROCSoft=1312
LimitMEMLOCK=65536
LimitMEMLOCKSoft=65536
LimitLOCKS=infinity
LimitLOCKSSoft=infinity
LimitSIGPENDING=1312
LimitSIGPENDINGSoft=1312
LimitMSGQUEUE=819200
LimitMSGQUEUESoft=819200
LimitNICE=0
LimitNICESoft=0
LimitRTPRIO=0
LimitRTPRIOSoft=0
LimitRTTIME=infinity
LimitRTTIMESoft=infinity

Display drop-in configuration files.

$ systemd-delta --type extended /etc/systemd/system/
[EXTENDED]   /usr/lib/systemd/system/redis-server.service → /etc/systemd/system/redis-server.service.d/limit_core.conf
[EXTENDED]   /usr/lib/systemd/system/redis-server.service → /etc/systemd/system/redis-server.service.d/limit_nofile.conf

2 overridden configuration files found.

Restart service to apply changes.

$ sudo systemctl restart redis-server

References

Along with a unit file foo.service, a "drop-in" directory foo.service.d/ may exist. All files with the suffix ".conf" from this directory will be parsed after the unit file itself is parsed. This is useful to alter or add configuration settings for a unit, without having to modify unit files. Drop-in files must contain appropriate section headers. For instantiated units, this logic will first look for the instance ".d/" sub-directory (e.g. "[email protected]/") and read its ".conf" files, followed by the template ".d/" sub-directory (e.g. "[email protected]/") and the ".conf" files there. Moreover for units names containing dashes ("-"), the set of directories generated by truncating the unit name after all dashes is searched too. Specifically, for a unit name foo-bar-baz.service not only the regular drop-in directory foo-bar-baz.service.d/ is searched but also both foo-bar-.service.d/ and foo-.service.d/. This is useful for defining common drop-ins for a set of related units, whose names begin with a common prefix. This scheme is particularly useful for mount, automount and slice units, whose systematic naming structure is built around dashes as component separators. Note that equally named drop-in files further down the prefix hierarchy override those further up, i.e. foo-bar-.service.d/10-override.conf overrides foo-.service.d/10-override.conf.