Czasy się zmieniają, podobnie jak najlepsze praktyki.
Prąd najlepszym sposobem na to jest do uruchomienia systemctl edit myservice
, który utworzy plik override dla ciebie lub pozwalają edytować istniejący.
W normalnych instalacjach utworzy to katalog /etc/systemd/system/myservice.service.d
, a wewnątrz tego katalogu utworzy się plik, którego nazwa kończy się na .conf
(zazwyczaj override.conf
), aw tym pliku możesz dodać lub zastąpić dowolną część jednostki dostarczoną przez dystrybucję.
Na przykład w pliku /etc/systemd/system/myservice.service.d/myenv.conf
:
[Service]
Environment="SECRET=pGNqduRFkB4K9C2vijOmUDa2kPtUhArN"
Environment="ANOTHER_SECRET=JP8YLOc2bsNlrGuD6LVTq7L36obpjzxd"
Pamiętaj również, że jeśli katalog istnieje i jest pusty, usługa zostanie wyłączona! Jeśli nie zamierzasz umieszczać czegoś w katalogu, upewnij się, że nie istnieje.
Dla porównania, stary sposób to:
Zalecanym sposobem jest utworzenie pliku /etc/sysconfig/myservice
zawierającego zmienne, a następnie załadowanie ich EnvironmentFile
.
Aby uzyskać szczegółowe informacje, zobacz dokumentację Fedory dotyczącą pisania skryptu systemowego .
sysconfig
ścieżka jest specyficzna dla Fedory, ale pytanie dotyczy Arch Linux. Myślę, że odpowiedź paluh jest bardziej interesująca/etc/sysconfig
jest specyficzny dla Fedory. AFAIR Arch Linux nalegał, aby pliki konfiguracyjne były gdzieś specyficzne dla pakietu, a nie w/etc
lokalizacji specyficznej dla Fedory. Na przykład/etc/myservice.conf
użycie dodatkowego pliku nie wydaje się tutaj dobrym rozwiązaniem.DJANGO_SETTINGS_MODULE=project.settings
jedna na linię.Odpowiedź zależy od tego, czy zmienna ma być stała (to znaczy nie powinna być modyfikowana przez użytkownika otrzymującego jednostkę), czy zmienna (powinna być ustawiona przez użytkownika).
Ponieważ jest to twoja jednostka lokalna, granica jest dość rozmyta i tak czy inaczej zadziałałoby. Jeśli jednak zaczniesz go rozpowszechniać i skończy się
/usr/lib/systemd/system
to, stanie się to ważne.Stała wartość
Jeśli wartość nie musi być zmieniana dla każdej instancji, preferowanym sposobem byłoby umieszczenie jej jako
Environment=
, bezpośrednio w pliku jednostki:Zaletą tego jest to, że zmienna jest przechowywana w jednym pliku z jednostką. Dlatego plik jednostki jest łatwiejszy do przenoszenia między systemami.
Zmienna wartość
Jednak powyższe rozwiązanie nie działa dobrze, gdy sysadmin ma lokalnie zmieniać wartość zmiennej środowiskowej. Mówiąc dokładniej, nowa wartość musiałaby być ustawiona przy każdej aktualizacji pliku jednostki.
W tym przypadku należy użyć dodatkowego pliku. Jak - zazwyczaj zależy od zasad dystrybucji.
Jednym szczególnie interesującym rozwiązaniem jest użycie
/etc/systemd/system/myservice.service.d
katalogu. W przeciwieństwie do innych rozwiązań ten katalog jest obsługiwany przez systemd i dlatego nie zawiera ścieżek specyficznych dla dystrybucji.W takim przypadku
/etc/systemd/system/myservice.service.d/local.conf
umieścisz taki plik, który doda brakujące części pliku jednostkowego:Następnie systemd łączy dwa pliki podczas uruchamiania usługi (pamiętaj, aby
systemctl daemon-reload
po zmianie jednego z nich). A ponieważ ta ścieżka jest używana bezpośrednio przez systemd, nie używaszEnvironmentFile=
do tego.Jeśli wartość ma zostać zmieniona tylko w niektórych systemach, których dotyczy problem, możesz połączyć oba rozwiązania, zapewniając domyślną wartość bezpośrednio w jednostce i lokalne zastąpienie w innym pliku.
źródło
systemctl daemon-reload
to polecenie przeładowania systemdEnvironmentFile=
jest lepszy, gdy wartości są tajne, takie jak hasła. Zobacz moją odpowiedź, aby poznać szczegóły.http://0pointer.de/public/systemd-man/systemd.exec.htec#Environment= - masz dwie opcje (jedną wskazał już Michael):
i
źródło
Odpowiedzi Michaela i Michała są pomocne i odpowiadają na pierwotne pytanie, jak ustawić zmienną środowiskową dla usługi systemowej. Jednak jednym z powszechnych zastosowań zmiennych środowiskowych jest konfigurowanie poufnych danych, takich jak hasła, w miejscu, które przypadkowo nie zostanie przydzielone do kontroli źródła za pomocą kodu aplikacji.
Jeśli dlatego chcesz przekazać zmienną środowiskową do usługi, nie używaj jej
Environment=
w pliku konfiguracji urządzenia. UżyjEnvironmentFile=
i wskaż inny plik konfiguracyjny, który jest możliwy do odczytania tylko przez konto usługi (i użytkowników z dostępem root).Szczegóły pliku konfiguracyjnego jednostki są widoczne dla każdego użytkownika za pomocą tego polecenia:
Wstawiam plik konfiguracyjny
/etc/my_service/my_service.conf
i tam umieszczam swoje sekrety:Następnie w pliku jednostki serwisowej użyłem
EnvironmentFile=
:Sprawdziłem, że
ps auxe
nie widzę tych zmiennych środowiskowych, a inni użytkownicy nie mają do nich dostępu/proc/*/environ
. Oczywiście sprawdź w swoim systemie.źródło
Michael dał jedno czyste rozwiązanie, ale chciałem zaktualizować zmienną env ze skryptu. Niestety wykonywanie poleceń bash w pliku jednostki systemowej nie jest możliwe. Na szczęście możesz uruchomić bash wewnątrz ExecStart:
http://www.dsm.fordham.edu/cgi-bin/man-cgi.pl?topic=systemd.service§=5
Przykład w naszym przypadku to:
źródło
/bin/bash -a -c 'source /etc/sysconfig/whatever && exec whatever-program'
. W-a
zapewnia środowisko jest eksportowana do sub-procesu (chyba, że chcesz poprzedzić wszystkie zmiennewhatever
zexport
)ExecStart=/usr/bin/env ENV=script /bin/myforegroundcmd
w tym przypadku jest trochę lepsze rozwiązanie.