4

Right now I have systemd service files with 20+ environment variables in them, expressed as Environment= This is a lot of duplication that I would like to git rid of since I have systemd files for celery, gunicorn, and celerybeat.

I'd like to have one file that is included into each of the unit files and it appears one way to do this is like this:

The correct way to do this is to create a directory named after the unit file with .d appended on the end. So for a unit called example.service, a subdirectory called example.service.d could be created. Within this directory a file ending with .conf can be used to override or extend the attributes of the system’s unit file.

But that still has me trapped in the name of the file matching the service name. My first thought was to symlink all of the services to the same folder so that gunicorn.d is a link to celery.d is a link to celerybeat.d. That way every service would have the same file and the only extra setup would be to create the links.

So, should I do that with Symlinks at the directory level or hard links at the file level under those directories.

OR am I going about this completely wrong and there is some super simple method to deal with this that I just haven't found.

1 Answer 1

8

Use EnvironmentFile=. That's one line per service file.

Also, convert your services to template units which can be started with different instances, e.g. having a [email protected] unit would allow you to start both [email protected] and [email protected], both sharing most of the same parameters – except for what's added or overridden through each instance's [email protected]/ directory. The instances can be individually controlled, enabled, etc.

Units can use %i to reference their instance, e.g. EnvironmentFile=/etc/webapps/%i.env would expand to "app1.env".

(Actually you're not required to have the template unit at all; you could do it the other way around, by having several real [email protected] units, and then overriding certain common parameters through the common [email protected]/.)

You can indeed symlink files inside .d/ directories – I would probably recommend doing that at file level, as this would retain the possibility of adding a second config file for that one weird service that needs special configuration. (Whereas if you symlink whole .d/ directories, then all of them must have the same content, no way around it.)

Recent systemd versions support a second mechanism very similar to instances, but implicitly using - as hierarchy separator. If you have a unit named foo-bar-baz.service, then configuration will also be loaded from foo-bar-.service.d/ and foo-.service.d/. This is mostly useful for other unit types like .slice, but can be used for services too. (Similarly to %i, the unit can reference the last dash-separated part of its name using %j.)


As a historical note, systemd used to have an .include /path/to/stuff keyword (predating the existence of .d directories) but this was removed in v246.

1
  • I used the EnvironmentFile= options. Not quite to the point of needing templated units yet since I only have 1 of each, but when I do, I'll convert them to template units.
    – boatcoder
    Commented Feb 4, 2022 at 16:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .