如何在systemd服务单元中启用virtualenv?


85

我想“激活” systemd服务文件中的virtualenv。

我想避免在systemd进程和python解释器之间有一个shell进程。

我当前的解决方案如下所示:

[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 }}

但我有麻烦。由于缺少sys.path中的某些实体,因此出现ImportErrors。


能否请您说明您收到的错误?
Praveen Yalagandula '16

@PraveenYalagandula跟踪不包含任何有用的信息,因为ImportError异常及其上方的所有行仅包含自定义代码,此处无关紧要。
盖特利

Answers:


112

virtualenv被“烘焙到virtualenv中的Python解释器中”。这意味着您可以启动pythonconsole_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
好点的尼尔斯。顺便说一句,在venv_home目录中没有fooservice.py,我想这是问题中的错字。
stelios

4
请注意,建议的打印命令与Python 3不兼容。如果至少使用python 2.4,则可以选择使用:python -m site获得sys.path变量的格式正确的输出以及其他信息。
马克·爱丁顿

2
整洁,我不知道python -m site。我已经调整了答案。
Nils Werner'3

1
@NilsWerner我最终通过生成一个外壳来解决了它,在Ubuntu 17.10上没有其他工作:github.com/umccr/pcgr-deploy/blob/master/ansible/files / ... ...请忽略jinja2模板的ansible,它部署后可以正确扩展。
头脑风暴

6
对于那些想知道这是否是ninja2 ....不,双花括号只是OP发明的占位符:superuser.com/questions/1209919/…–
ankostis

11

虽然库的路径确实包含在virtualenv的python解释器中,但是我对使用安装在virtualenv中的二进制文件的python工具遇到了问题。例如,我的Apache Airflow服务无法正常工作,因为它找不到gunicorn二进制文件。为了解决这个问题,这是我的ExecStart指令,其中包含Environment指令(仅为服务设置环境变量)。

ExecStart={{ virtualenv }}/bin/python {{ virtualenv }}/bin/airflow webserver
Environment="PATH={{ virtualenv }}/bin:{{ ansible_env.PATH }}"

ExecStart明确使用virtualenv的python解释器。我还添加了一个PATH变量,该变量在system之前添加了virtualenv的二进制文件夹PATH。这样,我就得到了所需的python库和二进制文件。

请注意,我使用ansible来构建此服务,因此请使用jinja2的花括号。


1

我不是使用virtualenv而是pyenv:这只是在shebang中使用真实的.pyenv路径,并确保它在PATH中

例如:pyenv为在产品中运行的用户mortenb激活flask-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

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文件夹的路径也是如此。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.