Как включить virtualenv в служебном модуле systemd?

87

Я хочу «активировать» виртуальный сервер в служебном файле 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 отсутствуют.

Геттли
источник
Не могли бы вы указать ошибки, которые вы получаете?
Правин Ялагандула
@PraveenYalagandula В трассировке нет никакой полезной информации, поскольку исключение ImportError и все строки над ним содержат только настраиваемый код, который здесь не имеет значения.
guettli

Ответы:

117

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
хорошее замечание Нильс. Кстати, fooservice.py не имеет смысла находиться внутри каталога venv_home, я полагаю, что это опечатка в вопросе.
stelios
4
Обратите внимание, что предлагаемые команды печати несовместимы с Python 3. Если вы используете как минимум python 2.4, вы можете в качестве альтернативы просто использовать: python -m siteдля получения красиво отформатированного вывода переменной sys.path вместе с дополнительной информацией.
Марк Эдингтон
2
Аккуратно, я не знала python -m site. Я скорректировал свой ответ.
Нильс Вернер,
1
@NilsWerner Я решил это, создав оболочку, на Ubuntu 17.10 больше ничего не работало: github.com/umccr/pcgr-deploy/blob/master/ansible/files/ ... ... пожалуйста, игнорируйте шаблон jinja2 для ansible, это правильно расширяется при развертывании.
мозговой штурм
6
Для тех, кто задается вопросом, является ли это ninja2 .... нет, двойные фигурные скобки - это просто заполнители, изобретенные ОП: superuser.com/questions/1209919/…
ankostis 06
12

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

Алексис Лессард
источник
1

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

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

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

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

#!/home/mortenb/.pyenv/versions/flask-prod/bin/python3
MortenB
источник
0

В моем случае я просто попытался добавить переменные среды, необходимые для Flask, например

[Service]
Environment="PATH=/xx/yy/zz/venv/bin"
Environment="FLASK_ENV=development"
Environment="APP_SETTINGS=config.DevelopmentConfig"

Я использовал virtualenv, поэтому /xx/yy/zz/venv/bin что это путь к папке virtualenv.

Себастьян Кардона Осорио
источник