Where do I put my systemd unit file?
I read that there are two folders for unit files (not in user mode).
/usr/lib/systemd/system/: units provided by installed packages /etc/systemd/system/: units installed by the system administrator
Conflicting with this understanding is the answer to this question: How to write startup script for Systemd. Can someone fill in the missing information so that I understand what is going on? (UPDATE: The answer has been updated, and my understanding no longer conflicts with it.)
Also, it seems that the scripts are organized in subfolders within the
In another location I read that there are other locations. It seems these are for user-specific services.
/usr/lib/systemd/user/ where services provided by installed packages go. /etc/systemd/user/ where system-wide user services are placed by the system administrator. ~/.config/systemd/user/ where the user puts its own services.
For the sake of others, here is a link to a related question I recently asked: Where do I put scripts executed by systemd units?
I’ve written 3, one for
ntpd, one for a second, static ethernet card, and one for running
p0f, the passive OS identifer. I put them all in
/etc/systemd/system. Looks like I could maybe let
systemd handle the NTP stuff, but I don’t think I want to rely on it that much.
/etc/systemd/system is where you put your scripts, pacman puts package scripts in
systemctl enable foo.service creates symlinks from
/etc. See the Unit Load Path section of
man systemd.unit(5) for more detail.
The best place to put system unit files:
Just be sure to add a target under the [Install] section, read "How does it know?" for details. UPDATE:
/usr/local/lib/systemd/system is another option, read "Gray Area" for details."
The best place to put user unit files:
but it depends on permissions and the situation. Note also that user services will only run while a user session is active.
The truth is that systemd units (or as the intro sentence calls them, "unit configurations") can go anywhere—provided you are willing to make manual symlinks and you are aware of the caveats. It makes life easier to put the unit where
systemctl daemon-reload can find it for some good reasons:
- Using a standard location means that systemd generators will find them and make them easy to enable at boot with
systemctl enable. This is because your unit will automatically be added to a unit dependency tree (a unit cache).
- You do not need to think about permissions, because only the right privileged users can write to the designated areas.
How does it know?
And how exactly does
systemctl enable know where to create the symlink? You hard code it within the
unit itself under the
[install] section. Usually there is a line like
[Install] WantedBy = multi-user.target
that corresponds to a predefined place on the filesystem.
systemctl knows that this unit is dependent on a group of unit files called
multi-user.target ("target" is the term used to designate unit dependency groups. You can list all groups with
systemctl list-units --type target). The group of unit files to be loaded with a target is put in a
targetname.target.wants directory. This is just a directory full of symlinks (or the real thing). If your
[Install] section says it is
multi-user.target, but if a symlink to it does not exist in the
multi-user.target.wants directory, then it will not load. When the systemd unit generators add your unit file to the dependency tree cache at boot (you can manually trigger generators with
systemctl daemon-reload), it automatically knows where to put the symlink—in this case in the directory
/etc/systemd/system/multi-user.target.wants/ should you enable it.
Key Points in the Manual:
Additional units might be loaded into systemd ("linked") from
directories not on the unit load path. See the link command for
Under systemctl, look for Unit File Commands
Unit File Load Path
Please read and understand the first sentence in the following quote from
man systemd.unit (because it implies that all of the paths I mention here may not apply to you if your systemd was compiled with different paths):
Unit files are loaded from a set of paths determined during compilation, described in the two tables below. Unit files found in directories listed earlier override files with the same name in directories lower in the list.
When the variable
$SYSTEMD_UNIT_PATHis set, the contents of this variable overrides the unit load path. If
$SYSTEMD_UNIT_PATHends with an empty component (":"), the usual unit load path will be appended to the contents of the variable.
Table 1 and Table 2 from
man systemd.unit are good.
Load paths when running in system mode (
/usr/lib/systemd/systemUnits of installed packages (or
/lib/systemd/systemin some cases, read
Load path when running in user mode (
There is a difference between per user units and all/global users units.
$XDG_CONFIG_HOME/systemd/userUser configuration (only used when
$HOME/.config/systemd/userUser configuration (only used when
$XDG_CONFIG_HOMEis not set)
$XDG_RUNTIME_DIR/systemd/userRuntime units (only used when
$XDG_DATA_HOME/systemd/userUnits of packages that have been installed in the home directory (only used when
$HOME/.local/share/systemd/userUnits of packages that have been installed in the home directory (only used when
$XDG_DATA_HOMEis not set)
--global (all users)
Units that apply to all users–meaning owned by each user, too. So each user can stop these services even if an administrator enables them at boot.
/etc/systemd/userLocal configuration for all users (
systemctl --global enable userunit.service)
/usr/lib/systemd/userUnits of packages that have been installed system-wide for all users (or
/lib/systemd/systemin some cases, read man systemd.unit)
On the one hand, the File Hierarchy Standard (also
man file-hierarchy) specifies that
/etc is for local configurations that do not execute binaries. On the other hand
it specifies that
/usr/local/ "is for use by the system administrator when installing software locally". You could also argue (if not just for the purpose of organization) that all system unit files should go under
/usr/local/lib/systemd/system, but this is intended for unit files that are part of "software" not from a package manager.
The corresponding systemd user units that are system-wide could go under
Another forgotten place is nowhere at all! Perhaps a lesser-known program is
systemd-run. You can use it to run transient units on the fly. see
For example, to schedule a reboot tomorrow morning at 4 a.m. (you might need
--force to ensure a reboot happens):
systemd-run -u restart --description="Restarts machine" --on-calendar="2020-12-18 04:00:00" systemctl --force reboot
This will yield a transient unit file
restart.service and a corresponding timer (because of the
--on-calendar, (and indicated by
transient=yes in the resulting transient unit definition).
# This is a transient unit file, created programmatically via the systemd API. Do not edit. [Unit] Description=Restarts machine [Service] ExecStart= ExecStart="/usr/bin/systemctl" "--force" "reboot"
Note that there is also the more dangerous double force option
--force --force, which tells the kernel to halt immediately (and, if you do not know what you’re doing, unsafely, because it is almost equivalent to cutting the power).
One noticeable difference between /etc/systemd/system and /lib/systemd/system on Debian/Ubuntu system is, the service files under /lib/systemd/system can be masked while those under /etc/systemd/system cannot. For example,
# ls /lib/systemd/system/mytest.service # systemctl mask mytest # ls /etc/systemd/system/mytest2.service # systemctl mask mytest2 Failed to mask unit: File /etc/systemd/system/mytest2.service already exists.
If you want to know all the places where systemd will look for unit files, the following commands should be helpful.
All folders which can contain user services:
These are the places where you can put your own per-user configs
systemd-analyze --user unit-paths
For administrative users, you may prefer putting your configs in the following folders (these will affect all users):
systemd-analyze --global unit-paths
All folders which can contain system services:
These will most likely be created by root and will affect the system as a whole
systemd-analyze --system unit-paths
There are many places
systemd looks for when you do
systemctl enable <unit-name>. Regardless of where they are found, they will be symbolically linked to somewhere inside
You can consult the
man systemd.unit(5) for a complete list, or use the
systemd-analyze commands as noted in other answers. You can put your unit files in any of these locations. but you must pay attention to
precedence and the
Precedence as in which folders will be preferred by systemd if a unit file was found with the same name.
Scope as in user, global, and system.
Selecting a Folder
For instance, if you put your unit files to
~/.config/systemd/user.control, then you would need to enable them with
systemctl enable --user <unit-file>.
Usually, the unit files are for services, and services are usually for the host. So, I mostly just put custom units into
/etc/systemd/system which is the system scope, and has precedence over anything and everything in case there is a name conflict.
pkg-config systemd --variable=systemdsystemconfdir pkg-config systemd --variable=systemduserunitdir pkg-config systemd --variable=systemduserconfdir
On my system, these returned in order:
/etc/systemd/system /usr/lib/systemd/user /etc/systemd/user