linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
  • Introduction
  • Lessons
  • How it works
  • Simulator
  • Knowledge base
  • Interview prep
Index
Categories
All entries
Footer
linuxlab-TutorialsPricingAboutPrivacy & cookies
Copyright © 2026 LinuxLab. All rights reserved.
home/linux/kb/Processes & resources/systemd-drop-ins

kb/processes ── Processes & resources ── intermediate

systemd drop-ins: override without editing the original

A drop-in is a `.conf` file in a `<unit>.d/` directory that merges into the unit file. It overrides any directive of a unit **without editing the original file** from the package.

view as markdownaka: drop-in, systemctl-edit, override-conf, systemd-override

Why not edit the unit directly

Say nginx came from a package as /usr/lib/systemd/system/nginx.service, and you need to raise LimitNOFILE. Historically there were three options:

  1. Edit the file straight in /usr/lib/systemd/system/. Bad, a package update overwrites it.
  2. Copy the whole thing into /etc/systemd/system/nginx.service and edit it. /etc/ wins on priority, but: a) you carry the entire file, b) on a package update, new directives from upstream will not show up for you.
  3. Drop-in, the one correct option: a small file holding the delta, while the base unit stays updatable.

How it works

For the unit nginx.service, systemd at load time merges every .conf file from these directories:

/usr/lib/systemd/system/nginx.service.d/*.conf   ← from packages (vendor)
/run/systemd/system/nginx.service.d/*.conf       ← runtime
/etc/systemd/system/nginx.service.d/*.conf       ← your local ones (highest)

Files inside one directory are merged in alphabetical order of the name. Convention: 10-foo.conf, 20-bar.conf. The numeric prefix sets the order.

There are also "shared" drop-in directories keyed by unit type:

  • service.d/ for all .service units
  • timer.d/ for all .timer units

That is why systemctl status often shows:

Drop-In: /usr/lib/systemd/system/service.d
         └─10-timeout-abort.conf, 50-keep-warm.conf

These are system-wide drop-ins that the distro applies to every service.

systemctl edit: the cleanest way to create one

Do not create a drop-in by hand. There is a command:

bash
sudo systemctl edit nginx.service

What happens:

  1. $EDITOR opens with an empty buffer and an instruction comment.
  2. After you save, systemd creates the file /etc/systemd/system/nginx.service.d/override.conf.
  3. It runs daemon-reload automatically.

IMPORTANT: write only what you change there, with the required [Section] header:

ini
[Service]
LimitNOFILE=65536
Environment="DEBUG=1"

Do not restate Description=, ExecStart=, and the rest. They are pulled in from the original.

Additive vs override-able directives

systemd directives fall into two classes:

List-style (additive). Wants=, Requires=, After=, ExecStartPre=, Environment=, EnvironmentFile=. By default a drop-in adds to the original list rather than replacing it.

Single-value (override). Type=, User=, Restart=, LimitNOFILE=. The drop-in simply overwrites.

To clear and redefine a list, you need an empty reset line BEFORE the new value:

ini
[Service]
ExecStart=                              # clear the entire original ExecStart
ExecStart=/usr/local/bin/nginx-wrapper  # set the new one

Without the first empty line, nginx starts twice: the original ExecStart plus the new one. This is the most common mistake.

The same goes for Environment=, Wants=, and other list-style directives:

ini
[Unit]
After=                # clear
After=postgres.service redis.service

Check the final result

bash
systemctl cat nginx.service

This shows the final unit with the drop-ins applied in the correct order. Every line is tagged with its source through # /path/to/file above each section:

# /usr/lib/systemd/system/nginx.service
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network-online.target
[Service]
Type=forking
ExecStart=/usr/sbin/nginx
...
# /etc/systemd/system/nginx.service.d/override.conf
[Service]
LimitNOFILE=65536

Next, systemd-analyze verify to check the syntax:

bash
systemd-analyze verify nginx.service

systemd-delta: what is overridden on my system

The command shows every unit on the system that has drop-ins or full overrides:

bash
systemd-delta --type=extended         # with drop-ins
systemd-delta --type=overridden       # units with a full override
systemd-delta --type=masked           # masked units (→ /dev/null)

Useful when you inherit a server from someone else and want to see what your predecessor admin set up.

systemctl revert: roll it back

Wipe all drop-ins and /etc/ overrides for a unit, leaving a clean vendor unit:

bash
sudo systemctl revert nginx.service

It deletes /etc/systemd/system/nginx.service.d/ and /etc/systemd/system/nginx.service itself if it was there as a full override.

Common cases

Raise limits:

ini
[Service]
LimitNOFILE=1048576
TasksMax=infinity

Change the User:

ini
[Service]
User=
User=newuser

(Single-value, so the empty line is not required, but writing it helps readability.)

Add an environment variable:

ini
[Service]
Environment="GOMAXPROCS=4"
Environment="OTEL_ENDPOINT=http://collector:4318"

Send logs to a separate file instead of journald:

ini
[Service]
StandardOutput=append:/var/log/myapp.log
StandardError=inherit

Do not forget daemon-reload if you edited without systemctl edit:

bash
sudo systemctl daemon-reload
sudo systemctl restart nginx

§ команды

bash
sudo systemctl edit nginx.service

Create a drop-in for nginx. Opens the editor and runs daemon-reload itself after you save

bash
systemctl cat nginx.service

Show the final unit with the applied drop-ins and their sources

bash
systemd-delta --type=extended

Every unit on the system that has drop-ins, an overview of the customization

bash
sudo systemctl revert nginx.service

Wipe all drop-ins and overrides, return to a clean vendor unit

bash
systemd-analyze verify /etc/systemd/system/nginx.service.d/override.conf

Check the drop-in syntax before a restart to catch errors early

§ см. также

  • systemdsystemd: the init system and service managersystemd is the Linux init system: PID 1 that starts everything else, tracks dependencies, restarts what crashes, and collects the logs.
  • systemd-unit-typessystemd unit typesA unit is a resource managed by systemd. The file extension equals the type: `.service` (daemon), `.socket` (lazy start on a socket), `.timer`, `.mount`, `.path`, `.slice`/`.scope` (cgroups), `.target` (a group).
  • cmd-systemctlsystemctl: managing systemd services`systemctl` is the main CLI for managing systemd units: services, timers, mounts, and sockets. It replaces SysV init and `service` on modern distros.
Footer
linuxlab-
Copyright © 2026 LinuxLab. All rights reserved.
Tutorials
Pricing
About
Privacy & cookies