it-swarm.com.de

Wie setze ich eine Umgebungsvariable im systemd Service?

Ich habe ein Arch Linux System mit systemd und ich habe meinen eigenen Dienst erstellt. Der Konfigurationsdienst unter /etc/systemd/system/myservice.service sieht aus wie das:

[Unit]
Description=My Daemon

[Service]
ExecStart=/bin/myforegroundcmd

[Install]
WantedBy=multi-user.target

Jetzt möchte ich eine Umgebungsvariable für das /bin/myforegroundcmd. Wie mache ich das?

188
lfagundes

Die Zeiten ändern sich und Best Practices auch.

Der aktuelle aktuelle beste Weg, dies zu tun, ist systemctl edit myservice Auszuführen, wodurch eine Überschreibungsdatei für Sie erstellt wird oder lassen Sie eine vorhandene bearbeiten.

In normalen Installationen wird ein Verzeichnis /etc/systemd/system/myservice.service.d Erstellt, und in diesem Verzeichnis wird eine Datei erstellt, deren Name auf .conf Endet (normalerweise override.conf). In dieser Datei können Sie hinzufügen einen Teil der von der Distribution gelieferten Einheit zu überschreiben oder zu überschreiben.

Zum Beispiel in einer Datei /etc/systemd/system/myservice.service.d/myenv.conf:

[Service]
Environment="SECRET=pGNqduRFkB4K9C2vijOmUDa2kPtUhArN"
Environment="ANOTHER_SECRET=JP8YLOc2bsNlrGuD6LVTq7L36obpjzxd"

Beachten Sie auch, dass Ihr Dienst deaktiviert wird, wenn das Verzeichnis vorhanden und leer ist! Wenn Sie nicht beabsichtigen, etwas in das Verzeichnis aufzunehmen, stellen Sie sicher, dass es nicht vorhanden ist.


Als Referenz war der alte Weg:

Der empfohlene Weg Um dies zu tun, erstellen Sie eine Datei /etc/sysconfig/myservice, Die Ihre Variablen enthält, und laden Sie sie dann mit EnvironmentFile.

Ausführliche Informationen finden Sie in der Fedora-Dokumentation zu Schreiben eines systemd-Skripts .

232
Michael Hampton

Die Antwort hängt davon ab, ob die Variable konstant sein soll (dh nicht vom Benutzer geändert werden soll, der die Einheit erhält) oder variabel sein soll (vom Benutzer festgelegt werden soll).

Da es sich um Ihre lokale Einheit handelt, ist die Grenze ziemlich verschwommen und so oder so würde es funktionieren. Wenn Sie jedoch mit der Verteilung beginnen und es in /usr/lib/systemd/system Endet, wird dies wichtig.

Konstanter Wert

Wenn sich der Wert nicht pro Instanz ändern muss, ist es am besten, ihn als Environment= Direkt in der Einheitendatei zu platzieren:

[Unit]
Description=My Daemon

[Service]
Environment="FOO=bar baz"
ExecStart=/bin/myforegroundcmd

[Install]
WantedBy=multi-user.target

Dies hat den Vorteil, dass die Variable mit dem Gerät in einer einzigen Datei gespeichert wird. Daher ist es einfacher, die Einheitendatei zwischen Systemen zu verschieben.

Variabler Wert

Die obige Lösung funktioniert jedoch nicht gut, wenn sysadmin den Wert der Umgebungsvariablen lokal ändern soll. Insbesondere müsste der neue Wert jedes Mal festgelegt werden, wenn die Einheitendatei aktualisiert wird.

In diesem Fall ist eine zusätzliche Datei zu verwenden. Wie - hängt normalerweise von der Vertriebsrichtlinie ab.

Eine besonders interessante Lösung ist die Verwendung des Verzeichnisses /etc/systemd/system/myservice.service.d. Im Gegensatz zu anderen Lösungen wird dieses Verzeichnis von systemd selbst unterstützt und enthält daher keine verteilungsspezifischen Pfade.

In diesem Fall platzieren Sie eine Datei wie /etc/systemd/system/myservice.service.d/local.conf, Die die fehlenden Teile der Einheitendatei hinzufügt:

[Service]
Environment="FOO=bar baz"

Anschließend führt systemd die beiden Dateien beim Starten des Dienstes zusammen (denken Sie daran, systemctl daemon-reload Zu verwenden, nachdem Sie eine der beiden Dateien geändert haben). Und da dieser Pfad direkt von systemd verwendet wird, verwenden Sie hierfür nicht EnvironmentFile=.

Wenn der Wert nur auf einigen der betroffenen Systeme geändert werden soll, können Sie beide Lösungen kombinieren und einen Standard direkt im Gerät und eine lokale Überschreibung in der anderen Datei angeben.

80
Michał Górny

http://0pointer.de/public/systemd-man/systemd.exec.html#Environment= - Sie haben zwei Möglichkeiten (eine, auf die Michael bereits hingewiesen hat):

Environment=

und

EnvironmentFile=
42
paluh

Die Antworten von Michael und Michał sind hilfreich und beantworten die ursprüngliche Frage, wie eine Umgebungsvariable für einen systemd-Dienst festgelegt wird. Eine häufig verwendete für Umgebungsvariablen besteht jedoch darin, vertrauliche Daten wie Kennwörter an einem Ort zu konfigurieren, der nicht versehentlich mit dem Code Ihrer Anwendung zur Quellcodeverwaltung verpflichtet wird.

Wenn Sie aus diesem Grund eine Umgebungsvariable an Ihren Dienst übergeben möchten, verwenden Sie nicht Environment= in der Gerätekonfigurationsdatei. Verwenden EnvironmentFile= und verweisen Sie auf eine andere Konfigurationsdatei, die nur vom Dienstkonto (und von Benutzern mit Root-Zugriff) gelesen werden kann.

Die Details der Gerätekonfigurationsdatei sind für jeden Benutzer mit diesem Befehl sichtbar:

systemctl show my_service

Ich habe eine Konfigurationsdatei bei /etc/my_service/my_service.conf und lege meine Geheimnisse dort hinein:

MY_SECRET=correcthorsebatterystaple

Dann habe ich in meiner Serviceeinheitsdatei EnvironmentFile=:

[Unit]
Description=my_service

[Service]
ExecStart=/usr/bin/python /path/to/my_service.py
EnvironmentFile=/etc/my_service/my_service.conf
User=myservice

[Install]
WantedBy=multi-user.target

Ich habe das überprüft ps auxe kann diese Umgebungsvariablen nicht sehen und andere Benutzer haben keinen Zugriff auf /proc/*/environ. Überprüfen Sie natürlich Ihr eigenes System.

18
Don Kirkby

Michael gab eine saubere Lösung, aber ich wollte die Env-Variable aus dem Skript aktualisieren. Leider ist das Ausführen von Bash-Befehlen in der systemd-Einheitendatei nicht möglich. Glücklicherweise können Sie in ExecStart Bash auslösen:

http://www.dsm.fordham.edu/cgi-bin/man-cgi.pl?topic=systemd.service&ampsect=5

Beachten Sie, dass diese Einstellung Shell-Befehlszeilen nicht direkt unterstützt. Wenn Shell-Befehlszeilen verwendet werden sollen, müssen sie explizit an eine Shell-Implementierung übergeben werden.

Beispiel in unserem Fall ist dann:

[Service]
ExecStart=/bin/bash -c "ENV=`script`; /bin/myforegroundcmd"
8
user1830432