Les temps changent, tout comme les meilleures pratiques.
Le meilleur moyen actuel de le faire est de l'exécuter systemctl edit myservice
, ce qui créera un fichier de remplacement ou vous permettra de modifier un fichier existant.
Dans les installations normales, cela créera un répertoire /etc/systemd/system/myservice.service.d
. À l'intérieur de ce répertoire, vous créerez un fichier dont le nom se termine par .conf
(généralement, override.conf
). Dans ce fichier, vous pouvez ajouter ou remplacer toute partie de l'unité fournie par la distribution.
Par exemple, dans un fichier /etc/systemd/system/myservice.service.d/myenv.conf
:
[Service]
Environment="SECRET=pGNqduRFkB4K9C2vijOmUDa2kPtUhArN"
Environment="ANOTHER_SECRET=JP8YLOc2bsNlrGuD6LVTq7L36obpjzxd"
Notez également que si le répertoire existe et est vide, votre service sera désactivé! Si vous n'avez pas l'intention de mettre quelque chose dans le répertoire, assurez-vous qu'il n'existe pas.
Pour référence, l'ancienne manière était:
Pour ce faire, il est recommandé de créer un fichier /etc/sysconfig/myservice
contenant vos variables, puis de les charger EnvironmentFile
.
Pour plus de détails, voir la documentation de Fedora sur la rédaction d'un script systemd .
Michael Hampton
la source
sysconfig
chemin est spécifique à Fedora mais la question concerne Arch Linux. La réponse de paluh est plus intéressante je pense/etc/sysconfig
est spécifique à Fedora. AFAIR Arch Linux insistait pour que les fichiers de configuration soient/etc
situés dans un emplacement spécifique à un paquet plutôt qu'à cet emplacement spécifique à Fedora. Par exemple/etc/myservice.conf
, utiliser un fichier supplémentaire ne semble pas être la bonne solution ici.DJANGO_SETTINGS_MODULE=project.settings
, une par ligne.La réponse dépend de si la variable est supposée être constante (c'est-à-dire, non censée être modifiée par l'utilisateur obtenant l'unité) ou variable (supposée être définie par l'utilisateur).
Puisqu'il s'agit de votre unité locale, la limite est assez floue et de toute façon cela fonctionnerait. Cependant, si vous commencez à le distribuer et que cela se termine
/usr/lib/systemd/system
, cela deviendra important.Valeur constante
Si la valeur n'a pas besoin de changer par instance, la méthode recommandée consiste à la placer
Environment=
directement dans le fichier unité:L'avantage de cela est que la variable est conservée dans un seul fichier avec l'unité. Par conséquent, le fichier d'unité est plus facile à déplacer entre les systèmes.
Valeur variable
Cependant, la solution ci-dessus ne fonctionne pas bien lorsque sysadmin est supposé changer la valeur de la variable d'environnement localement. Plus spécifiquement, la nouvelle valeur devra être définie chaque fois que le fichier d'unité est mis à jour.
Dans ce cas, un fichier supplémentaire doit être utilisé. Comment - dépend généralement de la politique de distribution.
Une solution particulièrement intéressante consiste à utiliser le
/etc/systemd/system/myservice.service.d
répertoire. Contrairement à d'autres solutions, ce répertoire est pris en charge par systemd lui-même et ne comporte donc aucun chemin spécifique à la distribution.Dans ce cas, vous placez un fichier comme
/etc/systemd/system/myservice.service.d/local.conf
celui-ci qui ajoute les parties manquantes du fichier unité:Ensuite, systemd fusionne les deux fichiers lors du démarrage du service (n'oubliez pas
systemctl daemon-reload
de modifier l'un des fichiers ). Et puisque ce chemin est utilisé directement par systemd, vous ne l'utilisez pasEnvironmentFile=
pour cela.Si la valeur n'est supposée être modifiée que sur certains des systèmes affectés, vous pouvez combiner les deux solutions, en fournissant une valeur par défaut directement dans l'unité et une substitution locale dans l'autre fichier.
la source
systemctl daemon-reload
est la commande pour recharger systemdEnvironmentFile=
C'est mieux quand les valeurs sont des secrets comme les mots de passe. Voir ma réponse pour plus de détails.http://0pointer.de/public/systemd-man/systemd.exec.html#Environment= - vous avez deux options (une déjà indiquée par Michael):
et
la source
Les réponses de Michael et Michał sont utiles et répondent à la question initiale de savoir comment définir une variable d'environnement pour un service systemd. Cependant, une utilisation courante des variables d'environnement consiste à configurer des données sensibles, telles que des mots de passe, dans un endroit qui ne sera pas accidentellement engagé dans le contrôle de source avec le code de votre application.
Si c'est la raison pour laquelle vous souhaitez transmettre une variable d'environnement à votre service, ne l' utilisez pas
Environment=
dans le fichier de configuration de l'unité. Utilisez-leEnvironmentFile=
et pointez-le sur un autre fichier de configuration lisible uniquement par le compte de service (et les utilisateurs ayant un accès root).Les détails du fichier de configuration de l'unité sont visibles par tout utilisateur à l'aide de cette commande:
Je mets un fichier de configuration à
/etc/my_service/my_service.conf
et met mes secrets dedans:Ensuite, dans mon fichier d'unité de service, j'ai utilisé
EnvironmentFile=
:J'ai vérifié que
ps auxe
ces variables d'environnement ne sont pas visibles et que les autres utilisateurs n'y ont pas accès/proc/*/environ
. Vérifiez sur votre propre système, bien sûr.la source
Michael a donné une solution propre mais je voulais obtenir la variable env mise à jour à partir du script. Malheureusement, l’exécution de commandes bash n’est pas possible dans le fichier d’unité systemd. Heureusement, vous pouvez déclencher bash dans ExecStart:
http://www.dsm.fordham.edu/cgi-bin/man-cgi.pl?topic=systemd.service§=5
Exemple dans notre cas est alors:
la source
/bin/bash -a -c 'source /etc/sysconfig/whatever && exec whatever-program'
. Les-a
garantit l'environnement est exporté vers le sous-processus (sauf si vous voulez préfixe toutes les variableswhatever
avecexport
)ExecStart=/usr/bin/env ENV=script /bin/myforegroundcmd
- être est-ce une meilleure solution dans ce cas.