Я хочу «активировать» виртуальный сервер в служебном файле 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 отсутствуют.
Ответы:
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
для получения красиво отформатированного вывода переменной sys.path вместе с дополнительной информацией.python -m site
. Я скорректировал свой ответ.Хотя путь к библиотекам действительно запечен в интерпретаторе 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.
источник
Я не использую 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
источник
В моем случае я просто попытался добавить переменные среды, необходимые для 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.источник