Python gunicorn是否应该在systemd service unit config中设置PATH和VIRTUAL_ENV环境变量,以便为Flask应用程序提供服务?

Python gunicorn是否应该在systemd service unit config中设置PATH和VIRTUAL_ENV环境变量,以便为Flask应用程序提供服务?,python,virtualenv,gunicorn,systemd,Python,Virtualenv,Gunicorn,Systemd,当使用gunicorn为Flask应用程序提供服务时,我认为我应该在gunicorn myapp:app之前激活venv,因为gunicorn与构成该应用程序的其他软件包和代码一起安装在venv中。在使用flask run或python myapp.py运行应用程序的场景中,需要首先激活venv(在我读过的每个教程和书中),因此在我看来,gunicorn案例没有理由有所不同 然后,当谈到让gunicorn成为systemd服务单元时,我知道在这个场景中没有办法像在interactive shel

当使用gunicorn为Flask应用程序提供服务时,我认为我应该在
gunicorn myapp:app
之前激活venv,因为gunicorn与构成该应用程序的其他软件包和代码一起安装在venv中。在使用
flask run
python myapp.py
运行应用程序的场景中,需要首先激活venv(在我读过的每个教程和书中),因此在我看来,gunicorn案例没有理由有所不同

然后,当谈到让gunicorn成为systemd服务单元时,我知道在这个场景中没有办法像在interactive shell中那样“激活一个venv”,我能想到的最接近的事情是将
Environment=“PATH=/PathToMyApp:other\u default\u PATH\u var\u contents”
Environment=“VIRTUAL\u ENV=/PathToMyApp/.venv”
放在配置中,以及
ExecStart=/PathToMyApp/.venv/bin/gunicorn myapp:app


然而,我发现我读过的教程中几乎没有一本像我想的那样添加这些环境选项。这些教程在这方面是错误的,还是环境变量对于虚拟环境中的gunicorn无关紧要?如果是后者,为什么?与
flask run
python myapp.py
案例有什么区别?

查看官方的gunicorn文档,上一节说您应该定义:

WorkingDirectory=/PathToMyApp
ExecStart=/PathToMyApp/.venv/bin/gunicorn myapp:app
这应该足够了,无需设置
路径
虚拟环境
环境变量

这些教程在这方面是错误的,还是环境变量对于虚拟环境中的gunicorn无关紧要?如果是后者,为什么?flask run和python myapp.py案例有什么区别

当在shell中激活虚拟环境的情况下运行
python myapp.py
时,它实际上运行的是虚拟环境的
bin
目录中的python解释器。您可以通过以下方式演示这一点:

这将显示您的系统:

/tmp $ which python
/usr/local/bin/python
激活venv:

/tmp $ . venv/bin/activate
(venv) /tmp $
(venv) /tmp $ which python
/tmp/venv/bin/python
这将在venv中显示python解释器:

/tmp $ . venv/bin/activate
(venv) /tmp $
(venv) /tmp $ which python
/tmp/venv/bin/python
此外,当您
cat-venv/bin/gunicorn
时,bang行指向该venv中的python解释器:

#!/tmp/venv/bin/python3

因此,当您在
systemd
单元文件中将其指定为
ExecStart
(或在不激活venv的情况下直接执行
venv/bin/gunicorn
)时,它实际上是在
venv/bin/python3
下运行的,这反过来使安装在该venv中的所有依赖项都可用于流程。

在虚拟环境中运行系统服务将是一种非常不寻常的安排。如果您在系统上下文中运行,只需在系统范围内安装依赖项。@tripleee对我来说,仅仅因为由systemd管理,相同的python代码就变得“不应该在虚拟环境中运行”,这是没有意义的。因为,如果我没有正确理解的话,virtualenv是用来解决系统范围的包版本冲突问题的,当两个或多个软件(都是用python编写的)需要使用systemd自动启动/重新启动时,这完全可能发生。此外,在本例中,它只是一个web应用程序,用于服务传入的HTTP请求。从同一个主机上提供两个web应用程序似乎是完全合理的,每个应用程序的依赖关系都得到了适当的维护。我并不是说不能或不应该这样做,只是解释了为什么它不常见。虽然如果你真的有这种需要,也许你的理解不应该仅仅基于你在随机博客帖子和论坛中找到的东西。当然,我知道通过激活一个venv,我们使用它的python解释器而不是系统解释器,venv中的gunicorn也是如此。我问这个问题是因为我提到了这两个环境变量,我想知道它们是否还有其他意义。现在我猜在纯web应用程序场景中,所有python代码都在同一个进程中运行,不涉及子进程,它们不会产生任何影响。顺便说一下,关于Syrd的GuniCORN文档根本不考虑虚拟EnV情况(ExcStase/Urr/Bi/GuniCogn XX.WSGI)。