I am trying to create a systemd service;
This service has a script that is supposed to use some environment variables;
So I created this:
cat /etc/systemd/system/atlantis-server.service [Service] ExecStart=/usr/local/bin/atlantis-server.sh
Which points to this
<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="36465d5744577657425a5758425f451b455344405344">[email protected]</a>:~$ cat /usr/local/bin/atlantis-server.sh #!/bin/bash source /etc/environment atlantis server --atlantis-url="$URL" --gitlab-user="$USERNAME" --gitlab-token="$TOKEN" --gitlab-webhook-secret="$SECRET" --gitlab-hostname="$HOSTNAME" --repo-whitelist="$REPO_WHITELIST"
What I noticed (after some errors in my systemd logs) is that I had to explicitly source /etc/environment
(this is where the above vars are declared).
Why is this needed?
Aren’t they globally visible?
edit: Adding this to the service definition did not solve the problem
Environment=/etc/environment
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
/etc/environment is not a global configuration file.
It applies only on Linux; only to PAM sessions, as employed by login and so forth; and only in the case where a particular PAM plug-in is installed and enabled on the system, and where that PAM plug-in has not been configured to use some other file (because /etc/environment is merely its default if it is not told otherwise). It is that PAM plug-in that reads it.
Otherwise, it is just a meaningless file in /etc that nothing uses.
Whilst you could set environment variables globally in systemd-system.conf, this applies to all services, not just to the ones that you are wanting to change.
Similarly, whilst an EnvironmentFile in the appropriate service unit(s) is a way to have systemd read a common file with a list of environment variable definitions, the systemd people discourage its use. They regard EnvironmentFile as a bad idea, and its use as a mistake.
The proper way to do this per the systemd people is to set each variable in the service unit with an Environment setting, which contains the actual environment variable name and value to be set, not a filename. This can either be directly in the relevant service unit, if as here one is writing one’s own service unit to be placed in /etc; or be in a .conf override file, if one is adjusting a pre-packaged service unit in /lib or /usr/lib.
Further reading
- https://unix.stackexchange.com/a/419061/5132
- Lennart Poettering et al. (2016).
systemd-system.conf. systemd manual pages. Freedesktop.org. - Lennart Poettering et al. (2016).
systemd.exec. systemd manual pages. Freedesktop.org. - Andrew G. Morgan and Thorsten Kukuk (August 2010). “pam_env — set/unset environment variables“. The Linux-PAM System Administrators’ Guide. linux-pam.org.
Method 2
The following is offered to provide clarity on what /etc/environment is/does, when it’s consulted and what package provides it:
whereis /etc/environment environment: /usr/lib/environment.d /etc/environment
Feeding the results of whereis above, we confirm /etc/environment is a SystemD file:
sudo dpkg -S /usr/lib/environment.d systemd, snapd: /usr/lib/environment.d
Consulting man environment.d, we are told the purpose of /etc/environment:
“The environment.d directories contain a list of “global” environment variable assignments for the user environment. systemd-environment-d-generator(8) parses them and updates the environment exported by the systemd user instance to the services it starts…. For backwards compatibility, a symlink to /etc/environment is installed, so this file is also parsed.”
Hope this cleared up any confusion. I know I was scratching my head a bit initially before I dug a bit deeper… 😉
Method 3
As you can see from the previous answer – Systemd doesn’t source that file when launching a service.
Adding this to the service definition did not solve the problem
Environment is used for inline definition of envvars (ex. Environment=KEY1=Value1). To read from a file use EnvironmentFile directive. The file that EnvironmentFile points to should be in following format:
Key1=Value1 Key2=Value2
It shouldn’t contain any shell substitutions or variable interpolations because Systemd is not a shell and can’t handle that info properly.
Method 4
Add the following to your service configuration:
EnvironmentFile=/etc/environment
@jeff-schaller please note this is not Environment= but EnvironmentFile= so you should not have deleted my answer. Indeed my answer does result in the variables from /etc/environment being made available to the service.
Method 5
No, environment variables is per-thread property, so no globally visible, just inherited from some parent or grandparent process. Systemd don’t read that file when launching system service.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0