如何在 systemd 服务单元中启用 virtualenv?
Posted
技术标签:
【中文标题】如何在 systemd 服务单元中启用 virtualenv?【英文标题】:How to enable a virtualenv in a systemd service unit? 【发布时间】:2016-09-09 17:11:34 【问题描述】:我想在 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
但是我遇到了麻烦。我收到 ImportErrors,因为 sys.path 中的某些实体丢失了。
【问题讨论】:
能否请您包括您遇到的错误? @PraveenYalagandula 回溯不包含任何有用的信息,因为 ImportError 异常及其上面的所有行仅包含自定义代码,这在此处无关紧要。 【参考方案1】:例如,我只是尝试添加 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 文件夹的路径。
【讨论】:
【参考方案2】:虽然库的路径确实融入了 virtualenv 的 python 解释器,但我遇到了使用安装在该 virtualenv 中的二进制文件的 python 工具的问题。例如,我的 apache 气流服务无法工作,因为它找不到 gunicorn
二进制文件。为了解决这个问题,这是我的ExecStart
指令,带有一个Environment
指令(它为服务单独设置一个环境变量)。
ExecStart= virtualenv /bin/python virtualenv /bin/airflow webserver
Environment="PATH= virtualenv /bin: ansible_env.PATH "
ExecStart
explicitly 使用 virtualenv 的 python 解释器。我还添加了一个PATH
变量,它在系统PATH
之前添加了virtualenv 的二进制文件夹。这样,我得到了所需的 python 库和二进制文件。
请注意,我使用 ansible 来构建此服务,因此使用 jinja2 的花括号。
【讨论】:
从字面上来寻找如何在服务中设置环境,因为气流找不到 gunicorn。没有失望!谢谢!我已经启动并运行了。 没错,我需要通过 Ansible 实现 Airflow 自动化。非常感谢:)【参考方案3】:virtualenv 被“烘焙到 virtualenv 中的 Python 解释器中”。这意味着您可以直接在该 virtualenv 中启动 python
或 console_scripts
,而无需先激活 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
【讨论】:
好点尼尔斯。顺便说一句, fooservice.py 在 venv_home 目录中没有意义,我想这是问题中的一个错字。 请注意,建议的打印命令与 Python 3 不兼容。如果您至少使用 python 2.4,您也可以使用:python -m site
以获得格式良好的 sys.path 变量输出以及其他信息。
很好,我不知道python -m site
。我已经调整了答案。
当您启动的 python 进程期望激活 virtualenv 时,此方法不起作用。例如,考虑 venv_home /bin/python -m newrelic.admin run-program python -m myapp
。这将在 venv 中启动 python,调用 New Relic,然后它将无法启动应用程序,因为 python
不在路径中,因为 venv 未激活。
对于那些想知道这是否是 ninja2 的人......不,双花括号只是 OP 发明的占位符:superuser.com/questions/1209919/…【参考方案4】:
我没有使用 virtualenv 而是 pyenv:这里只是在 shebang 中使用真正的 .pyenv 路径并确保它在 PATH 中
例如:pyenv 为在 prod 中运行的用户 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
【讨论】:
以上是关于如何在 systemd 服务单元中启用 virtualenv?的主要内容,如果未能解决你的问题,请参考以下文章