uwsgi vassal 不使用虚拟环境

uwsgi vassal 不使用虚拟环境

我正在运行一个由 uwsgi 主服务器启动的 Python 应用程序。该应用程序应该在特定的 venv 中运行,但我无法让它工作。

应用程序的 ini 文件指定使用 python3.8 创建的 venv。但应用程序仍在使用 python3.6 运行,无法访问 venv 中安装的 python 模块。

Emperor 在装有 python3.6 的虚拟环境中运行。但是,该虚拟环境中安装的 python 模块在我的应用程序中也不可用。

我可能缺少一些配置,但我无法确定是哪一个。我查看了下面列出的帖子以及官方 uwsgi 文档。

这是我的 ini 文件:

[uwsgi]
socket = /tmp/new.embeetle.uwsgi.sock
chdir = /srv/new.embeetle/app
wsgi-file = app.py
logto = /tmp/new.embeetle.uwsgi.log
enable-threads
virtualenv = /srv/new.embeetle/app/env

我尝试添加下面两行(但没有真正理解它们的含义),但没有效果:

plugin = python3.8
home = /srv/new.embeetle/app/env

这是我接触 ini 文件后在日志文件 /tmp/new.embeetle.uwsgi.log 中得到的内容:

Fri Oct 16 23:56:51 2020 - received message 1 from emperor
...gracefully killing workers...
Gracefully killing worker 1 (pid: 23275)...
worker 1 buried after 1 seconds
binary reloading uWSGI...
chdir() to /srv/uwsgi/vassals
closing all non-uwsgi socket fds > 2 (max_fd = 1024)...
found fd 3 mapped to socket 0 (/tmp/new.embeetle.uwsgi.sock)
running /srv/uwsgi/uwsgi/bin/uwsgi
*** has_emperor mode detected (fd: 6) ***
[uWSGI] getting INI configuration from new.embeetle.ini
*** Starting uWSGI 2.0.19.1 (64bit) on [Fri Oct 16 23:56:52 2020] ***
compiled with version: 7.5.0 on 16 October 2020 20:28:25
os: Linux-4.15.0-101-generic #102-Ubuntu SMP Mon May 11 10:07:26 UTC 2020
nodename: foechoer.sikando.com
machine: x86_64
clock source: unix
detected number of CPU cores: 6
current working directory: /srv/uwsgi/vassals
detected binary path: /srv/uwsgi/uwsgi/bin/uwsgi
!!! no internal routing support, rebuild with pcre support !!!
chdir() to /srv/new.embeetle/app
your processes number limit is 80112
your memory page size is 4096 bytes
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uwsgi socket 0 inherited UNIX address /tmp/new.embeetle.uwsgi.sock fd 3
Python version: 3.6.9 (default, Jul 17 2020, 12:50:27)  [GCC 8.4.0]
PEP 405 virtualenv detected: /srv/new.embeetle/app/env
Set PythonHome to /srv/new.embeetle/app/env
Python main interpreter initialized at 0x55af44ec7410
python threads support enabled
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 145840 bytes (142 KB) for 1 cores
*** Operational MODE: single process ***

接下来是我的应用程序的输出,由于 python 版本错误和缺少模块而失败。

关于如何实现这一点,您有什么建议吗?我需要提供更多信息吗?

答案1

由于没有人回答我的问题,我做了进一步的研究并找到了答案。我在其他帖子中没有找到明确的答案,所以我会在这里发布它以防其他人遇到类似的问题。我不得不阅读一些 uwsgi 源代码才能真正理解这个问题。我是否错过了一些明显的 uwsgi 文档来源,还是文档缺乏?

首先,虚拟环境uwsgi的选项有三个同义词:韦恩pyhome具有完全相同的效果。在其他帖子中查找信息时,了解这一点很有用。

使用这些选项的效果与激活虚拟环境(在命令行上)的效果不同。激活虚拟环境时,您还会更改 PATH,以便获取该虚拟环境的 python 版本。然而,在 uwsgi 中,python 代码是使用链接到 uwsgi 可执行文件的 python .so/.dll 直接调用的,因此执行代码的 python 版本始终是 uwsgi 链接的版本,无论给出任何 virtualenv 选项。

但是有一个解决方案。如果你在目标虚拟环境中安装 uwsgi,比如在 /my/virtual/env,你可以将以下内容添加到你的 .ini 文件中:

unprivileged-binary-patch = /my/virtual/env/bin/uwsgi

(或者--unprivileged-binary-patch /my/virtual/env/bin/uwsgi在命令行上)用目标环境的版本替换当前的 uwsgi,这将与所需的 python 版本链接。它还将激活虚拟环境,而无需添加 virtualenv 选项。

注意非特权二进制补丁不能与皇帝暴君模式(原因我不清楚)。使用非特权二进制补丁,禁用皇帝暴君模式并确保vassal的ini文件不能被不受信任的用户编辑。

当尝试非特权二进制补丁,请确保运行应用程序的用户(通常使用 uid 和 gid 选项指定)对目标环境具有读取权限。例如,如果您使用 uid = www-data 和 gid = www-data,请运行

chmod -R www-data:www-data /my/virtual/env

如果不这样做,您可能会收到此错误:

Fatal Python error: Py_Initialize: Unable to get the locale encoding
ModuleNotFoundError: No module named 'encodings'

至少可以说,这对于查明问题没有什么帮助。

相关内容