Python 如何在 systemd 服务单元中启用 virtualenv?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37211115/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to enable a virtualenv in a systemd service unit?
提问by guettli
I want to "activate" a virtualenv in a systemd service file.
我想在 systemd 服务文件中“激活”一个 virtualenv。
I would like avoid to have a shell process between the systemd process and the python interpreter.
我想避免在 systemd 进程和 python 解释器之间有一个 shell 进程。
My current solution looks like this:
我目前的解决方案是这样的:
[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
/etc/sysconfig/fooservice.env
PATH={{ venv_home }}/bin:/usr/local/bin:/usr/bin:/bin
PYTHONIOENCODING=utf-8
PYTHONPATH={{ venv_home }}/...
VIRTUAL_ENV={{ venv_home }}
But I am having trouble. I get ImportErrors since some enties in sys.path are missing.
但我遇到了麻烦。由于缺少 sys.path 中的某些条目,我收到了 ImportErrors。
回答by Nils Werner
The virtualenv is "baked into the Python interpreter in the virtualenv". This means you can launch python
or console_scripts
directly in that virtualenv and don't need to activate the virtualenv first or manage PATH
yourself.:
virtualenv 被“烘焙到 virtualenv 中的 Python 解释器中”。这意味着您可以启动python
或console_scripts
直接在该 virtualenv 中启动,而无需先激活 virtualenv 或自行管理PATH
。:
ExecStart={{ venv_home }}/bin/fooservice --serve-in-foreground
or
或者
ExecStart={{ venv_home }}/bin/python {{ venv_home }}/fooservice.py --serve-in-foreground
and remove the EnvironmentFile
entry.
并删除EnvironmentFile
条目。
To verify that it is indeed correct you can check sys.path
by running
要验证它确实正确,您可以sys.path
通过运行来检查
{{ venv_home }}/bin/python -m site
and comparing the output to
并将输出与
python -m site
回答by Alexis Lessard
While the path for libraries is indeed baked into the python interpreter of the virtualenv, I've had issues with python tools that were using binaries installed in that virtualenv. For instance, my apache airflow service wouldn't work because it couldn't find the gunicorn
binary. To work around this, here's my ExecStart
instruction, with an Environment
instruction (which sets an environment variable for the service alone).
虽然库的路径确实被嵌入到 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 uses the python interpreter of the virtualenv. I'm also adding a PATH
variable, which adds the binary folder of the virtualenv before the system PATH
. That way, I get the desired python libraries as well as binaries.
ExecStart
显式使用 virtualenv 的 python 解释器。我还添加了一个PATH
变量,它在 system 之前添加了 virtualenv 的二进制文件夹PATH
。这样,我就获得了所需的 Python 库和二进制文件。
Note that I'm using ansible to build this service, ergo the curly braces of jinja2.
请注意,我使用 ansible 来构建此服务,因此使用 jinja2 的花括号。
回答by Sebastian Cardona Osorio
In my case I just tried to add environment variables required for Flask, for instance
就我而言,我只是尝试添加 Flask 所需的环境变量,例如
[Service]
Environment="PATH=/xx/yy/zz/venv/bin"
Environment="FLASK_ENV=development"
Environment="APP_SETTINGS=config.DevelopmentConfig"
I was using virtualenv so /xx/yy/zz/venv/bin
is the path of virtualenv folder.
我使用的是 virtualenv /xx/yy/zz/venv/bin
,virtualenv 文件夹的路径也是如此。
回答by MortenB
I'm not using virtualenv but pyenv: here is it just to use the real .pyenv path in the shebang and make sure it is in the PATH
我不是在使用 virtualenv 而是 pyenv:这里只是在 shebang 中使用真实的 .pyenv 路径并确保它在 PATH 中
Ex: pyenv activate flask-prod for user mortenb which is running in prod
例如:pyenv 为在 prod 中运行的用户 mortenb 激活 flask-prod
/home/mortenb/.pyenv/versions/flask-prod/bin/python --version
Python 3.6.2
Then to my flask scripts starting in systemd *.service I add the following shebang:
然后在以 systemd *.service 开头的烧瓶脚本中添加以下shebang:
#!/home/mortenb/.pyenv/versions/flask-prod/bin/python3