【问题标题】:How to enable a virtualenv in a systemd service unit?如何在 systemd 服务单元中启用 virtualenv?
【发布时间】: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 异常及其上面的所有行仅包含自定义代码,这在此处无关紧要。

标签: python environment-variables virtualenv


【解决方案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 }}"
    

    ExecStartexplicitly 使用 virtualenv 的 python 解释器。我还添加了一个PATH 变量,它在系统PATH 之前添加了virtualenv 的二进制文件夹。这样,我得到了所需的 python 库和二进制文件。

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

    【讨论】:

    • 从字面上来寻找如何在服务中设置环境,因为气流找不到 gunicorn。没有失望!谢谢!我已经启动并运行了。
    • 没错,我需要通过 Ansible 实现 Airflow 自动化。非常感谢:)
    【解决方案3】:

    virtualenv 被“烘焙到 virtualenv 中的 Python 解释器中”。这意味着您可以直接在该 virtualenv 中启动 pythonconsole_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
    

    【讨论】:

      猜你喜欢
      • 2018-05-31
      • 2017-12-11
      • 2022-10-23
      • 1970-01-01
      • 2021-01-08
      • 2015-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多