在Windows上生产环境中部署Flask
我找到了一些关于在Linux/Unix上运行Flask的指南,这些指南涉及了很多技术,比如nginx、apache、uWSGI、gunicorn等等。不过,所有这些方法似乎在Linux上效果最好,而在Windows上要么偶尔能用,要么根本就不能用。那么,有没有推荐的方法可以在Windows环境下把Flask应用部署到生产环境中呢?
5 个回答
我推荐以下方法:
- 使用IIS
- ... 确保启用了IIS的CGI/FastCGI模块
- ... 使用wfastcgi这个Python模块来在IIS FastCGI下托管一个Python WSGI网络应用
如果设置正确,在IIS上部署一个Python网络应用非常简单,甚至可以不需要在IIS管理界面里点来点去,只需编辑网站或应用的web.config
文件即可。
我在Windows上成功地使用了简单的Twisted Web服务器来运行Flask网站。 请问其他人也在Windows上成功使用Twisted吗?这样可以确认这个配置是否有效。
new_app.py
if name == "main":
reactor_args = {}
def run_twisted_wsgi():
from twisted.internet import reactor
from twisted.web.server import Site
from twisted.web.wsgi import WSGIResource
resource = WSGIResource(reactor, reactor.getThreadPool(), app)
site = Site(resource)
reactor.listenTCP(5000, site)
reactor.run(**reactor_args)
if app.debug:
# Disable twisted signal handlers in development only.
reactor_args['installSignalHandlers'] = 0
# Turn on auto reload.
import werkzeug.serving
run_twisted_wsgi = werkzeug.serving.run_with_reloader(run_twisted_wsgi)
run_twisted_wsgi()
old_app.py
if name == "main":
app.run()
一个可能的办法,虽然我觉得会很复杂,就是让你的 Flask 应用在 Windows 的 Linux 子系统中运行。
网上已经有一些教程教你如何从这个子系统调用 PowerShell 脚本,比如这个链接:https://www.raymondcamden.com/2017/09/25/calling-a-powershell-script-from-wsl
你说得太对了。在Windows上安装东西就像是把方形的木头塞进圆形的洞里,挺难的。Apache和mod_wsgi可能是最合适的选择,但在Linux系统上安装这些东西会简单得多,像用pip、apt-get这些工具,操作起来都很顺畅。那在Windows服务器上运行一个Linux虚拟机,会不会是个不错的折中方案呢?
我之前做过几次这个,性能影响不大。你需要利用IIS和FastCGI。
这里有一篇博客文章,详细介绍了一种方法:https://medium.com/@bilalbayasut/deploying-python-web-app-flask-in-windows-server-iis-using-fastcgi-6c1873ae0ad8
这里还有一个StackOverflow的帖子,介绍了同样的方法:https://stackoverflow.com/a/22107980/8508792
为了防止帖子被删,这里也把内容放在下面...
总体概述
HTTP -> IIS -> ISAPI -> FastCGI -> WSGI(Flask应用程序)
设置步骤
步骤1:安装所需的程序
- 安装Python(2.7或3.x,我用的是3.3)
- 安装pip-Win(我用的是1.6版本)
- 安装pywin32(我用的是218版本)
- 安装IIS FastCGI扩展,使用fcgisetup 1.5
步骤2:安装可选的二进制包
我使用这个网站的安装程序.exe安装了pyodbc
。从源代码安装(例如,使用pip在虚拟环境中安装)需要一个C/C++编译器。
步骤3:获取wfastcgi.py
的副本
选择一个适合你的版本,最好是支持Python 3.3的版本(我用的是David Ebbo的版本)。你也可以选择“官方”版本从这里。
将wfastcgi.py
脚本安装到C:\Inetpub\wwwroot
,并确保提供应用程序的账户(默认是“网络服务”)有读取权限。
步骤4:将virtualenv
安装到系统的site-packages中
C:\Python33\Scripts\pip.exe install virtualenv
(如果你使用的是Python 3.3,并且在默认位置安装了一切)
步骤5:安装你的Flask应用程序
你可以在系统的任何地方安装应用程序。你可以考虑在
C:\Inetpub
下安装。为了本教程,我们将应用程序的根文件夹称为%APPROOT%
。(环境变量中不要加引号。)确保提供应用程序的账户(默认是“网络服务”)对所有脚本文件有读取权限。这个命令:
cacls "%APPROOT%" /S:"D:PAI(A;OICI;FA;;;BA)(A;OICIIO;FA;;;CO)(A;OICI;0x1200a9;;;NS)(A;OICI;FA;;;SY)"
将为你的应用程序目录赋予以下权限:
- BUILTIN\Administrators: 对该文件夹、子文件夹和文件的完全控制
- CREATOR OWNER: 仅对子文件夹和文件的完全控制
- NT AUTHORITY\NETWORK SERVICE: 对该文件夹、子文件夹和文件的读取权限
- NT AUTHORITY\SYSTEM: 对该文件夹、子文件夹和文件的完全控制
添加任何必要的本地配置(我的应用程序使用一个local.cnf文件,版本控制系统会忽略它)--例如,数据库的URL。
确保你的应用程序在
%APPROOT%
中包含一个Web.config
文件--有关文件格式的信息,请参见下面的部分。
步骤6:为你的应用程序创建一个virtualenv
C:\Python33\Scripts\virtualenv.exe --system-site-packages "%APPROOT%\env"
(如果你的应用程序已经使用了这个目录,请选择其他名称。)
步骤7:在virtualenv中安装你的应用程序所需的包
cd "%APPROOT%"
env\Scripts\activate
pip install -r Packages
(我的项目将需求规范保存在一个名为Packages
的文件中。)
步骤8:为你的应用程序创建一个网站或虚拟目录
使用inetmgr.msc
(开始 -> 运行…,然后在编辑框中输入inetmgr
并按ENTER)启动Internet Information Services (IIS) Manager。确保为你创建的节点(网站或虚拟目录)设置本地路径为Flask应用程序的根文件夹。wfastcgi.py
使用本地路径来识别要处理请求的Flask应用程序。
为节点授予读取和脚本(运行脚本)权限。
步骤9:配置fcgiext.ini
这个文件位于步骤1中安装的fcgiext.dll
的同一目录下(默认是%SYSTEMROOT%\system32\inetsrv
)。
在配置这个文件时,你需要几个参数:
- {site id}: 你可以在Internet Information Services (IIS) Manager的详细信息(右侧)窗格中找到的数字站点ID,当左侧树状图选择“网站”时。
- {application name}:
fcgiext.ini
中提供FastCGI(ISAPI)处理程序参数的部分名称。你可以选择这个值--选择一个能代表你应用程序的名称。 - {path to app}: 对于虚拟目录,网站内的URL路径到要处理的虚拟目录。
- {approot}: 你的应用程序根目录的路径。
使用这些参数来:
将FastCGI请求映射到处理部分:
- 对于整个网站,添加
*:{site id}={application name}
到[Types]
部分。 - 对于虚拟目录,添加
*:/lm/w3svc/{site id}/root/{path to app}={application name}
到[Types]
部分。
- 对于整个网站,添加
添加一个处理部分(
[{application name}]
),并为这个应用程序提供参数(完整参考):ExePath={approot}\env\python.exe
Arguments=C:\Inetpub\wwwroot\wfastcgi.py
(或wfastcgi.py
适配器脚本安装的其他位置)EnvironmentVars=ENV_VAR1:value,ENV_VAR2:value,等等。
(请参见完整参考以了解引号规则)。这是设置你的WSGI_LOG环境变量的好地方--确保提供网站的账户(默认是“网络服务”)对文件有写权限,并且(如果文件不存在)有权限在包含目录中添加文件。
步骤10:为目标URL配置FastCGI处理
使用Internet Information Services (IIS) Manager,从要由你的Flask应用程序提供服务的节点(网站或虚拟目录)的上下文(右键)菜单中选择“属性...”并:
在“主目录”选项卡(网站)或“虚拟目录”选项卡(虚拟目录)中,点击“配置...”按钮。
在“通配符应用程序映射”部分,使用“插入...”按钮添加一个通配符映射:
- 可执行文件是步骤1中安装的FastCGI扩展DLL。它的默认位置是
%SYSTEMROOT%\system32\inetsrv\fcgiext.dll
。 - 确保“验证文件是否存在”未被选中。Flask应用程序会自行路由,这与磁盘上的文件没有必然关系。
- 可执行文件是步骤1中安装的FastCGI扩展DLL。它的默认位置是
Web.config
这个文件在这个设置中是由wfastcgi.py
读取的,而不是由IIS读取。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<applicationSettings>
<add key=“PYTHONPATH” value=“”/>
<add key=“WSGI_HANDLER” value=“module.application”/>
</applicationSettings>
</configuration>
<add>
元素添加环境变量(os.environ
在Python中)。WSGI_HANDLER
必须指定--它告诉wfastcgi.py
如何找到WSGI应用程序对象。如果值以“()”结尾,wfastcgi.py
将调用命名对象,期望它返回一个WSGI应用程序对象。PYTHONPATH
被特殊处理--wfastcgi.py
在调用WSGI应用程序之前对PYTHONPATH
的值执行(环境)变量扩展(使用Windows标准的%VAR%
表示法),然后在分号处分割结果并将条目附加到sys.path
。因为wfastcgi.py
在导入包含WSGI应用程序对象的模块之前,将当前目录更改为作为网站或虚拟目录的本地路径,包含一个空字符串在PYTHONPATH中将导致搜索包括你的Flask应用程序目录作为起始点。你也可以在fcgiext.ini
中设置PYTHONPATH(在这种情况下,它将由解释器包含在sys.path
中,然后再由wfastcgi.py
包含)。WSGI_RESTART_FILE_REGEX
提供一个Python正则表达式,用于过滤应触发FastCGI处理程序进程重启的文件更改通知。设置这个以在源文件或配置文件更改时触发。我使用(?i).*\.(py|cnf|config)$
。WSGI_LOG
可以在这里设置,但我认为在fcgiext.ini
中设置更好。
对于IIS 7
在IIS 7中,FastCGI的一些东西发生了巨大的变化。从这个版本开始,FastCGI通过IIS直接支持,而不是通过扩展进行配置(也就是说,步骤1.4不再必要,fcgiext.ini
不再控制IIS 7+的FastCGI行为,也不需要创建/编辑它)。相反,确保在控制面板 > 程序和功能 > 启用或关闭Windows功能中的Internet Information Services下启用CGI。
Web.config
IIS 7是第一个从Web.config
文件读取与FastCGI相关的配置设置的IIS版本。你的Web.config
文件需要在<configuration>
元素中包含一个<system.webServer>
元素,其中包含一个<handlers>
元素,里面有一个<add>
元素,属性如下:
- path:
*
- verb:
*
- modules:
FastCgiModule
- resourceType:
Unspecified
- requireAccess:
Script
- scriptProcessor: 这个比较复杂
scriptProcessor
属性
这个<add>
元素的属性必须包含你想要使用的Python解释器.exe
文件的完整路径(在你的Python虚拟环境的Scripts
子文件夹中)后面跟一个|
,然后是你正在使用的wfastcgi.py
文件的完整路径。由于这些路径依赖于运行你应用程序的机器的设置,你可能希望在部署过程中设置这个属性。
IIS服务器级别的设置
- 在
inetmgr
中,点击树中的服务器节点,然后在中心窗格中选择FastCGI设置。会弹出一个可执行文件/参数对的列表。 - 为你的
python.exe
和正在使用的wfastcgi.py
的完整路径添加一个条目。两者都应该以在你的Web.config
中的<handlers>/<add>
元素中显示的方式给出。 - 确保在新的FastCGI应用程序条目中设置
PYTHONPATH
环境变量,以包括你的应用程序代码库的根目录。在Web.config
的<applicationSettings>
中添加空的PYTHONPATH
条目的建议可能不适用于这个版本的IIS。