Chcę „aktywować” virtualenv w pliku usługi systemd.
Chciałbym uniknąć procesu powłoki między procesem systemd a interpreterem Pythona.
Moje obecne rozwiązanie wygląda następująco:
[Unit]
Description=fooservice
After=syslog.target network.target
[Service]
Type=simple
User=fooservice
WorkingDirectory={{ venv_home }}
ExecStart={{ venv_home }}/fooservice --serve-in-foreground
Restart=on-abort
EnvironmentFile=/etc/sysconfig/fooservice.env
[Install]
WantedBy=multi-user.target
/etc/sysconfig/fooservice.env
PATH={{ venv_home }}/bin:/usr/local/bin:/usr/bin:/bin
PYTHONIOENCODING=utf-8
PYTHONPATH={{ venv_home }}/...
VIRTUAL_ENV={{ venv_home }}
Ale mam kłopoty. Otrzymuję ImportErrors, ponieważ brakuje niektórych encji w sys.path.
python
environment-variables
virtualenv
guettli
źródło
źródło
Odpowiedzi:
Virtualenv jest „wstawiany do interpretera Pythona w virtualenv”. Oznacza to, że możesz uruchomić
python
lubconsole_scripts
bezpośrednio w tym virtualenv i nie musisz najpierw aktywować virtualenv aniPATH
samodzielnie zarządzać :ExecStart={{ venv_home }}/bin/fooservice --serve-in-foreground
lub
ExecStart={{ venv_home }}/bin/python {{ venv_home }}/fooservice.py --serve-in-foreground
i usuń
EnvironmentFile
wpis.Aby sprawdzić, czy rzeczywiście jest poprawny, możesz sprawdzić
sys.path
, uruchamiająci porównując dane wyjściowe z
źródło
python -m site
aby uzyskać ładnie sformatowane wyjście zmiennej sys.path wraz z dodatkowymi informacjami.python -m site
. Dostosowałem odpowiedź.Chociaż ścieżka do bibliotek jest rzeczywiście wypalona w interprecie języka Python w virtualenv, miałem problemy z narzędziami Pythona, które korzystały z plików binarnych zainstalowanych w tym virtualenv. Na przykład moja usługa przepływu powietrza Apache nie działałaby, ponieważ nie mogła znaleźć
gunicorn
pliku binarnego. Aby obejść ten problem, oto mojaExecStart
instrukcja zEnvironment
instrukcją (która ustawia zmienną środowiskową dla samej usługi).ExecStart={{ virtualenv }}/bin/python {{ virtualenv }}/bin/airflow webserver Environment="PATH={{ virtualenv }}/bin:{{ ansible_env.PATH }}"
ExecStart
jawnie używa interpretera języka Python w virtualenv. Dodam teżPATH
zmienną, która dodaje folder binarny virtualenv przed systememPATH
. W ten sposób otrzymuję pożądane biblioteki Pythona, a także pliki binarne.Zauważ, że używam ansible do tworzenia tej usługi, czyli nawiasów klamrowych jinja2.
źródło
Nie używam virtualenv, ale pyenv: tutaj wystarczy, aby użyć prawdziwej ścieżki .pyenv w shebang i upewnić się, że jest w PATH
Przykład: pyenv aktywuj kolbę-prod dla użytkownika mortenb, który działa w prod
/home/mortenb/.pyenv/versions/flask-prod/bin/python --version Python 3.6.2
Następnie do moich skryptów flask zaczynających się w systemd * .service dodaję następujący shebang:
#!/home/mortenb/.pyenv/versions/flask-prod/bin/python3
źródło
W moim przypadku po prostu próbowałem dodać zmienne środowiskowe wymagane na przykład dla Flaska
[Service] Environment="PATH=/xx/yy/zz/venv/bin" Environment="FLASK_ENV=development" Environment="APP_SETTINGS=config.DevelopmentConfig"
Użyłem virtualenv, więc
/xx/yy/zz/venv/bin
jest to ścieżka do folderu virtualenv.źródło