简体   繁体   English

Flask 应用程序使用错误的 Python 解释器——需要知道如何“编译”mod_wsgi 以使用特定的 Python 版本

[英]Flask App using wrong Python interpreter - need to know how to "compile" mod_wsgi to work with specific Python version

TL;DR , I need to know how to "compile" a WSGI file in such a way that it uses a different Python interpreter than when I initially installed mod_wsgi. TL;DR ,我需要知道如何以使用与我最初安装 mod_wsgi 时不同的 Python 解释器的方式“编译”WSGI 文件。

This is my first Flask app/website, so hopefully you can forgive a little bit of ignorance.这是我的第一个 Flask 应用程序/网站,希望您能原谅我的一些无知。 I'll try to give you the relevant details.我会尽量给你相关的细节。

I have a Flask app running on a Ubuntu server via Nginx/Apache (reverse proxy setup).我有一个通过 Nginx/Apache(反向代理设置)在 Ubuntu 服务器上运行的 Flask 应用程序。 My folder structure is like this:我的文件夹结构是这样的:

|----MyApp
|------MyApp.wsgi
|------MyApp
|--------__init__.py
|--------templates
|--------static
|--------requirements.txt
|--------venv

I was getting weird exceptions thrown from my app, and discovered my Flask app was running the wrong version of the Python interpreter, thus some of the code wasn't working as expected.我的应用程序抛出了奇怪的异常,并发现我的 Flask 应用程序运行了错误版本的 Python 解释器,因此一些代码没有按预期工作。 I have pyenv installed, and Python 3.8.1 set as global, but when the app runs through Apache, it's using Python 2.7.17 (the version that comes with Ubuntu 18.04).我安装了 pyenv,并将 Python 3.8.1 设置为全局,但是当应用程序通过 Apache 运行时,它使用的是 Python 2.7.17(Ubuntu 18.04 附带的版本)。 I figured out at least part of the problem.我至少解决了部分问题。 I was following along with this tutorial: https://www.digitalocean.com/community/tutorials/how-to-deploy-a-flask-application-on-an-ubuntu-vps我正在关注本教程: https ://www.digitalocean.com/community/tutorials/how-to-deploy-a-flask-application-on-an-ubuntu-vps

At one point, the tutorial has you do sudo pip install Flask , which seems to install Flask "globally" (ie, outside of the venv, which seems to defeat the purpose).有一次,本教程让您执行sudo pip install Flask ,这似乎是“全局”安装 Flask(即,在 venv 之外,这似乎违背了目的)。 Not sure if i'm using the correct terminology.不确定我是否使用了正确的术语。 So I had been doing:所以我一直在做:

python3 -m venv venv
source venv/bin/activate
sudo pip install Flask

Then when I would run my app, either through Apache, or even just from a terminal window, i'd print to a.txt file the sys.version , so I could see the Python interpreter it was using, and voila, it's using 2.7.17, not 3.8.1.然后,当我通过 Apache 或什至只是从终端窗口运行我的应用程序时,我会将sys.version打印到 a.txt 文件,这样我就可以看到它正在使用的 Python 解释器,瞧,它正在使用2.7.17,不是 3.8.1。 So by trial and error, I learned that sudo pip install Flask wasn't what I wanted.因此,通过反复试验,我了解到sudo pip install Flask不是我想要的。 pip install Flask (when run with my venv activated) produces the result I want when I run my Flask app from the terminal:当我从终端运行 Flask 应用程序时, pip install Flask (在激活我的 venv 的情况下运行)会产生我想要的结果:

source venv/bin/activate
export FLASK_APP=__init__.py
flask run

And BAM, I get the correct version of Python, 3.8.1.而 BAM,我得到了正确的 Python 版本 3.8.1。 However, now I have a new problem.但是,现在我有一个新问题。 When I restart Apache and try to go to my website, Apache gives the following error: Exception occurred processing WSGI script '/var/www/MyApp/MyApp.wsgi' and ImportError: No module named flask当我重新启动 Apache 并尝试访问我的网站时,Apache 出现以下错误: Exception occurred processing WSGI script '/var/www/MyApp/MyApp.wsgi' and ImportError: No module named flask

I think I need to tell Apache or WSGI (or whoever) where my Flask installation is, since it is only installed within the venv.我想我需要告诉 Apache 或 WSGI(或任何人)我的 Flask 安装在哪里,因为它只安装在 venv 中。 I found this SO post: Flask - WSGI - No module named 'flask'我找到了这篇 SO 帖子: Flask - WSGI - No module named 'flask'

And tried the suggested solution, using the python-path directive in my Apache config, like so:并尝试了建议的解决方案,在我的 Apache 配置中使用python-path指令,如下所示:

  WSGIScriptAlias / /var/www/MyApp/MyApp.wsgi
  # WSGIDaemonProcess MyApp python-home=/var/www/MyApp/MyApp/venv
  WSGIDaemonProcess MyApp python-path=/var/www/MyApp:/var/www/MyApp/MyApp/venv/lib/python3.8/site-packages
  WSGIProcessGroup MyApp

And BAM, my app works again, but HEY why is it using Python 2.7.17 still? BAM,我的应用程序再次运行,但嘿,为什么它仍然使用 Python 2.7.17? I followed the link that one of the commenters posted, regarding the use of virtual environments with WSGI: https://modwsgi.readthedocs.io/en/develop/user-guides/virtual-environments.html我点击了其中一位评论者发布的关于使用 WSGI 的虚拟环境的链接: https ://modwsgi.readthedocs.io/en/develop/user-guides/virtual-environments.html

From what I gathered, I must've installed mod_wsgi before installing pyenv and Python 3.8.1.根据我收集到的信息,我必须在安装 pyenv 和 Python 3.8.1 之前安装 mod_wsgi。 So mod_wsgi is "compiled" with an old version of Python, and you can't use a virtual environment to force mod_wsgi to use a different python version than the one it was installed/compiled with.所以 mod_wsgi 是用旧版本的 Python “编译”的,你不能使用虚拟环境来强制 mod_wsgi 使用与安装/编译时不同的 python 版本。 How do I reinstall and compile mod_wsgi so that it works off of my preferred Python version?如何重新安装和编译 mod_wsgi 以便它可以在我首选的 Python 版本上运行?

Edit: I tried doing编辑:我试过

sudo apt-get --purge remove libapache2-mod-wsgi
sudo apt-get install libapache2-mod-wsgi-py3

However, now my app uses Python 3.6.9 (system version that came with Ubuntu 18.04).但是,现在我的应用程序使用 Python 3.6.9(Ubuntu 18.04 附带的系统版本)。 So it appears this method of installation ignores my pyenv settings (Python 3.8.1).所以看起来这种安装方法忽略了我的 pyenv 设置(Python 3.8.1)。 Am I able to override this and specify a python version somehow?我可以覆盖它并以某种方式指定 python 版本吗?

After much googling, trial and error, and self-loathing, I figured it out.经过多次谷歌搜索、反复试验和自我厌恶之后,我明白了。 I tried many different ways of installing mod_wsgi that didn't work.我尝试了很多不同的方法来安装 mod_wsgi,但都没有用。 I found a StackOverflow post that showed me one of the gotchas that was standing in my way, which was that I had not installed python 3.8.1 using pyenv with the shared libraries option set: Run mod_wsgi with pyenv我发现了一个 StackOverflow 帖子,它向我展示了一个阻碍我前进的陷阱,那就是我没有使用设置了共享库选项的 pyenv 安装 python 3.8.1: Run mod_wsgi with pyenv

So I did:所以我做了:

pyenv uninstall 3.8.1
CONFIGURE_OPTS=--enable-shared pyenv install 3.8.1

Then I was able to activate my virtual environment, and install mod_wsgi locally to my app.然后我能够激活我的虚拟环境,并在本地将 mod_wsgi 安装到我的应用程序中。

rm -rf venv
python3 -m venv venv
source venv/bin/activate
pip install Flask
pip install mod_wsgi

Then I had to tell apache which wsgi file to use.然后我必须告诉 apache 使用哪个 wsgi 文件。 Luckily, there's a command you can run to show what to tell Apache:幸运的是,您可以运行一个命令来显示要告诉 Apache 的内容:

mod_wsgi-express module-config

Which outputs something like this:哪个输出是这样的:

LoadModule wsgi_module "/var/www/MyApp/MyApp/venv/lib/python3.8/site-packages/mod_wsgi/server/mod_wsgi-py38.cpython-38-x86_64-linux-gnu.so"
WSGIPythonHome "/var/www/MyApp/MyApp/venv"

And I slapped that into the file: /etc/apache2/mods-available/wsgi.load我将其放入文件中: /etc/apache2/mods-available/wsgi.load

Restart apache, and SHAZAM.重新启动 apache 和 SHAZAM。 My app/website is running on Python 3.8.1!我的应用程序/网站在 Python 3.8.1 上运行!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM