如何在IIS中部署Flask应用程序?

35

有没有人能帮我在IIS 6上运行Flask应用程序? 我尝试使用isapi-wsgi,但是当我访问虚拟目录地址时,会出现一个页面,上面写着“找不到指定的模块”。 还有其他选项吗?

以下是我为isapi-wsgi编写的Python脚本。 虚拟目录已创建,在IIS Manager中看起来一切正常,但是站点无法工作。

from wof import app
import os

app.secret_key=os.urandom(24)

import isapi_wsgi
def __ExtensionFactory__():
    return isapi_wsgi.ISAPISimpleHandler(app)

if __name__ == '__main__':
    from isapi.install import *
    params = ISAPIParameters()
    sm = [ScriptMapParams(Extension="*", Flags=0)]
    vd = VirtualDirParameters(Name="WOFPy_Sondes", Description="ISAPI-WSGI for WOFPY Sondes test", ScriptMaps=sm, ScriptMapUpdate="replace")
    params.VirtualDirs = [vd]
    HandleCommandLine(params)
3个回答

66

高级概述

HTTP -> IIS -> ISAPI -> FastCGI -> WSGI (Flask应用)


设置步骤

第一步:安装所需二进制文件

  1. 安装Python(2.7或3.x -- 我使用的是3.3版本)
  2. 安装pip-Win(我使用的是1.6版本)
  3. 安装pywin32(我使用的是218版本)
  4. 使用fcgisetup 1.5安装IIS FastCGI扩展

第二步:安装可选的二进制包

我使用从此网站下载的.exe安装了pyodbc。从源代码安装(例如pip,用于安装到虚拟环境中)需要C/C++编译器。

第三步:获取wfastcgi.py副本

选择适合自己的版本,最好支持Python 3.3(我使用了David Ebbo的版本)。您可能需要从这里获取“官方”版本。

wfastcgi.py脚本安装到C:\Inetpub\wwwroot中,并确保将为您的应用程序提供服务的帐户(默认为“Network Service”)具有对其的读取访问权限。

第四步:在系统site-packages中安装 virtualenv

C:\Python33\Scripts\pip.exe install virtualenv

(如果您使用的是 Python 3.3 并将所有文件安装在默认位置)

步骤 5:安装 Flask 应用程序

  • 您可以将应用程序安装在系统上的任何位置。 您可能想将其安装在 C:\Inetpub 下面。 对于本教程,我们将称您的应用程序安装根文件夹为 %APPROOT%。(不要在环境变量中加入引号。)

  • 确保将服务您的应用程序的帐户(默认为“Network Service”)具有读取所有脚本文件的权限。 运行以下命令:

  • 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"
    

    如果您的应用程序已经使用了该目录,请选择除env之外的其他名称。

    步骤7:将应用程序所需的软件包安装到虚拟环境中

    cd "%APPROOT%"
    env\Scripts\activate
    pip install -r Packages
    

    (我的项目将需求规范存储在名为Packages的文件中。)

    第八步:为您的应用程序创建网站或虚拟目录

    使用 inetmgr.msc开始 -> 运行...,然后输入 inetmgr 在编辑框中并按下 ENTER)来启动 Internet Information Services (IIS) Manager。确保将所创建的节点(网站或虚拟目录)的本地路径设置为 Flask 应用程序的根文件夹。wfastcgi.py 使用本地路径来标识要处理请求的 Flask 应用程序。

    将节点的读取脚本(运行脚本)权限都给予。

    第九步:配置fcgiext.ini

    该文件位于与第1步安装的 fcgiext.dll 相同的目录中(默认情况下,是 %SYSTEMROOT%\system32\inetsrv)。

    在配置此文件时,您需要几个参数:

    • {site id}:当从窗口左侧的树中选择“Web Sites”时,在Internet Information Services (IIS) Manager 的详细信息(右侧)窗格中可以找到的数值 Site ID。
    • {application name}:在 fcgiext.ini 中提供 FastCGI (ISAPI) 处理程序参数的部分名称。您可以选择此值 -- 选择某个代表您的应用程序的东西。
    • {path to app}:对于虚拟目录,是要处理的 Web Site 内的 URL 路径到虚拟目录。
    • {approot}:应用程序根目录的路径。

    使用这些参数:

    • 将 FastCGI 请求映射到处理部分:

      • 对于整个 Web Site,在 [Types] 部分添加 *:{site id}={application name}
      • 对于虚拟目录,在 [Types] 部分添加 *:/lm/w3svc/{site id}/root/{path to app}={application name}
    • 添加一个处理部分([{application name}]),其中包含这个应用程序的参数(完整参考):

      • ExePath={approot}\env\python.exe
      • Arguments=C:\Inetpub\wwwroot\wfastcgi.py (或者替换成你安装 wfastcgi.py 适配器脚本的位置)
      • EnvironmentVars=ENV_VAR1:value, ENV_VAR2:value,等等 (查看完整参考资料获取引号规则)。这是设置您的 WSGI_LOG 环境变量 的好地方 - 确保为提供站点的帐户(默认情况下为“Network Service”)赋予文件写入权限并且(如果文件不存在)允许添加文件到包含目录中。

      步骤10:为目标URL配置FastCGI处理

      使用 Internet Information Services (IIS) Manager,从上下文(右键单击)菜单中选择要由您的Flask应用程序提供服务的节点(Web Site或Virtual Directory)的“属性...”:

      • 在“主目录”选项卡(Web Site)或“虚拟目录”选项卡(Virtual Directory)中,单击“配置...”按钮。

      • 在“通配符应用程序映射”部分,使用“插入...”按钮添加通配符映射:

        • 可执行文件是安装在步骤1中的FastCGI扩展DLL。其默认位置为 %SYSTEMROOT%\system32\inetsrv\fcgiext.dll
        • 确保“验证文件是否存在”未选中。Flask应用程序执行它们自己的路由,这与磁盘上的文件没有必然联系。

      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>元素添加环境变量(Python中的os.environ)。

      • WSGI_HANDLER必须指定--它告诉wfastcgi.py如何定位WSGI应用程序对象。如果值以“()”结尾,wfastcgi.py将调用命名对象,期望它返回一个WSGI应用程序对象。

      • PYTHONPATH被特殊处理--wfastcgi.pyPYTHONPATH的值执行(环境)变量扩展(使用Windows标准的%VAR%符号),然后在分号处分割结果,并将条目附加到sys.path中,然后调用WSGI应用程序。由于wfastcgi.py将当前目录更改为Web Site或Virtual Directory的本地路径所指定的路径之前,导入包含WSGI应用程序对象的模块,因此在PYTHONPATH中包含空字符串将导致搜索将您的Flask应用程序目录包括在起点。您还可以在fcgiext.ini中设置PYTHONPATH(在这种情况下,解释器通过包括它在sys.path中,然后再次由wfastcgi.py包括它)。

      • WSGI_RESTART_FILE_REGEX提供用于过滤应触发FastCGI处理程序进程重启的路径的文件更改通知的Python正则表达式。将其设置为在更改源文件或配置文件时触发。我使用(?i).*\.(py|cnf|config)$

      • WSGI_LOG可以在此处设置,但我认为在fcgiext.ini中设置更好。


      对于IIS 7

      一些快速CGI事物在IIS 7中发生了巨大变化。从这个版本开始,快速CGI直接通过IIS支持,并且不是通过扩展配置的(即步骤1.4不必要,fcgiext.ini不控制IIS 7+的FastCGI行为,也没有必要创建/编辑它)。相反,请确保在控制面板>程序和功能>打开或关闭Windows功能下启用CGI

      Web.config

      IIS 7是第一个从Web.config文件读取与FastCGI相关的配置设置的版本。您的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.exewfastcgi.py的完整路径。这两个应该与它们在Web.config中的<handlers>/<add>元素中的方式相同。
      • 确保在新的FastCGI应用程序条目中设置了PYTHONPATH环境变量,以包括您的应用程序代码库的根目录。关于在Web.config<applicationSettings>中添加一个空的PYTHONPATH条目的建议可能不适用于这个版本的IIS。

2
这是一个很好的总结,只需要进行小的调整,因为在过去的6年中,Windows Server/IIS发生了变化,即默认用户现在是IIS_USRS而不再是Network Service。您可能需要使用位于C:\ windows \ system32 \ inetsrv中的appcmd命令解锁配置的某些部分,使用命令appcmd unlock config / section:handler - AndrewWhalan
1
单个工作进程下是否能够运行多个线程?因为当我部署应用程序时,它会为每个请求创建一个新的Python进程。 - AutomationNerd
根据IIS FastCGI配置文件(fcgiext.ini),“池中的每个进程一次只能处理一个请求。每个请求完成后,该进程将返回到池中等待另一个请求。” - ReWrite

3

你确定你的答案吗? - Lutaaya Huzaifah Idris

0

我从未使用过IIS,但是IIS支持CGI网关,因此您应该能够通过WSGI适应CGI。

IIS <--> CGI <--> WSGI

要将WSGI作为CGI脚本运行,您可以使用Python标准库中的CGIHandler


7
除非是非常低流量的东西(例如仅由您自己使用),否则CGI不是一个可接受的解决方案。每次请求页面时,它都会启动一个进程。 - ThiefMaster

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接