Подтвердить что ты не робот

Как включить виртуальную машину в сервисном блоке systemd?

Я хочу "активировать" 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, поскольку некоторые из них в sys.path отсутствуют.

4b9b3361

Ответ 1

Virtualenv "запекается в интерпретаторе Python в virtualenv". Это означает, что вы можете запускать python или console_scripts непосредственно в этом virtualenv и вам не нужно сначала активировать virtualenv или управлять PATH самостоятельно.

ExecStart={{ venv_home }}/bin/fooservice --serve-in-foreground

или же

ExecStart={{ venv_home }}/bin/python {{ venv_home }}/fooservice.py --serve-in-foreground

и удалите запись EnvironmentFile.

Чтобы убедиться, что это действительно правильно, вы можете проверить sys.path, запустив

{{ venv_home }}/bin/python -m site

и сравнивая вывод

python -m site

Ответ 2

Несмотря на то, что путь к библиотекам действительно встроен в интерпретатор python для virtualenv, у меня были проблемы с инструментами python, которые использовали двоичные файлы, установленные в этом virtualenv. Например, мой сервис Apache gunicorn не будет работать, потому что он не может найти gunicorn файл 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.

Ответ 3

Я не использую virtualenv, но pyenv: вот только для того, чтобы использовать реальный путь .pyenv в shebang и убедиться, что он находится в PATH

Ex: pyenv активирует flask-prod для пользователя mortenb, который работает в prod

/home/mortenb/.pyenv/versions/flask-prod/bin/python --version
Python 3.6.2

Затем, чтобы мои скрипты, начинающиеся с systemd *.service, добавляли следующий shebang:

#!/home/mortenb/.pyenv/versions/flask-prod/bin/python3