Я хочу "активировать" virtualenv в systemd сервисном файле.
Я хотел бы, стараются не иметь процесс оболочки между процессом systemd и интерпретатором Python.
Мое текущее решение похоже на это:
[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 }}
Но я испытываю затруднения. Я получаю ImportErrors, так как некоторые enties в sys.path отсутствуют.
В то время как путь для библиотек действительно испекся в интерпретатор Python virtualenv, у меня были проблемы с инструментами Python, которые использовали двоичные файлы, установленные в этом virtualenv. Например, мой апачский сервис потока воздуха не работал бы, потому что он не мог найти gunicorn
двоичный файл. Для работы вокруг этого вот, мой ExecStart
инструкция, с Environment
инструкция (который устанавливает переменную среды для одного только сервиса).
ExecStart={{ virtualenv }}/bin/python {{ virtualenv }}/bin/airflow webserver
Environment="PATH={{ virtualenv }}/bin:{{ ansible_env.PATH }}"
ExecStart
явно использование интерпретатор Python virtualenv. Я также добавляю PATH
переменная, которая добавляет двоичную папку virtualenv перед системой PATH
. Тем путем я получаю желаемые библиотеки Python, а также двоичные файлы.
Примечание, что я использую ansible для создания этого сервиса, следовательно фигурные скобки jinja2.