为 Python Web 应用配置 IIS

将 Internet Information Services (IIS) 用作 Windows 计算机(包括 Azure 上的 Windows 虚拟机)上的 Web 服务器时,需要配置 Python Web 应用程序,以使 IIS 能够正确处理 Python 代码。 该配置是通过 Python Web 应用的 web.config 文件中的设置完成的。 本文介绍如何配置必要的设置。

先决条件

  • 安装了 Windows 上的 Python。 若要运行 Web 应用,请先直接在 Windows 主机上安装相应版本的 Python,如安装 Python 解释器中所述。

    • 确定 python.exe 解释器的位置。 为方便起见,可以将此位置添加到 PATH 环境变量中。
  • 安装了所需程序包。 对于专用主机,可使用全局 Python 环境(而不是虚拟环境)运行应用。 相应地,只需运行 pip install -r requirements.txt 命令,即可将应用的所有要求都安装到全局环境中。

将 web.config 设置为指向 Python 解释器

Python 应用程序的 web.config 文件会指示 Windows 上运行的 IIS Web 服务器(版本 7 或更高版本),应如何通过 HttpPlatformHandler(推荐)或 FastCGI 处理 Python 请求。 Visual Studio 2015 及更早版本会自动进行这些修改。 对于 Visual Studio 2017 及更高版本,必须手动修改 web.config 文件。

如果项目尚未包含 web.config 文件,则可以通过右键单击项目目录、选择“添加”>“新项”并搜索 web.config 或创建空白的 web.config 文件来添加一个。

选项 1:配置 HttpPlatformHandler

HttpPlatform 模块将套接字连接直接传递到独立的 Python 进程。 借助此传递可根据需要运行任何 Web 服务器,但需要用于运行本地 Web 服务器的启动脚本。 此方法通常通过使用 Python Web 框架(如 Flask 或 Django)来完成。 在 web.config 文件的 <httpPlatform> 元素中指定脚本。 processPath 属性指向站点扩展的 Python 解释器。 arguments 属性指向运行本地 Web 服务器的启动脚本,本例中为 runserver.py,以及要提供的所有参数:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <add name="PythonHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified"/>
    </handlers>
    <httpPlatform processPath="c:\python36-32\python.exe"
                  arguments="c:\home\site\wwwroot\runserver.py --port %HTTP_PLATFORM_PORT%"
                  stdoutLogEnabled="true"
                  stdoutLogFile="c:\home\LogFiles\python.log"
                  startupTimeLimit="60"
                  processesPerApplication="16">
      <environmentVariables>
        <environmentVariable name="SERVER_PORT" value="%HTTP_PLATFORM_PORT%" />
      </environmentVariables>
    </httpPlatform>
  </system.webServer>
</configuration>

在此示例中,HTTP_PLATFORM_PORT 环境变量包含本地服务器用来侦听来自 localhost 的连接的端口。 此示例还演示如何创建其他环境变量 SERVER_PORT。 可以根据需要创建和分配环境变量。

选项 2:配置 FastCGI 处理程序

或者,你可以使用 FastCGI 配置应用。 FastCGI 是在请求级别工作的接口。 IIS 接收传入的连接,并将每个请求转发到在一个或多个持久 Python 进程中运行的 WSGI 应用。

注意

尽管可以使用 FastCGI 设置项目,但我们建议使用 HttpPlatformHandler 配置应用,因为 WFastCGI 项目不再被维护,并且可能导致 bug。

若要使用 FastCGI,请先安装并配置 wfastcgi 包,如 pypi.org/project/wfastcgi/ 所述。

接下来,修改应用程序的 web.config 文件,以在 python.exe 键中添加 wfastcgi.py 可执行文件和 PythonHandler 文件的完整路径。 以下步骤假定 Python 安装在 c:\python36-32 文件夹中,应用代码位于 c:\home\site\wwwroot 文件夹中。 相应地调整路径的这些值。

  1. 修改 PythonHandler 文件中的 web.config 条目,使路径与 Python 安装位置匹配。 有关详细信息,请参阅 IIS 配置参考 (iis.net)。

    <system.webServer>
       <handlers>
         <add name="PythonHandler" path="*" verb="*" modules="FastCgiModule"
             scriptProcessor="c:\python36-32\python.exe|c:\python36-32\wfastcgi.py"
             resourceType="Unspecified" requireAccess="Script"/>
       </handlers>
    </system.webServer>
    
  2. web.config 文件的 <appSettings> 部分中,为 WSGI_HANDLERWSGI_LOG(可选)和 PYTHONPATH 添加键:

    <appSettings>
       <add key="PYTHONPATH" value="c:\home\site\wwwroot"/>
       <!-- The handler here is specific to Bottle; see the next section. -->
       <add key="WSGI_HANDLER" value="app.wsgi_app()"/>
       <add key="WSGI_LOG" value="c:\home\LogFiles\wfastcgi.log"/>
    </appSettings>
    

    应用可以将这些 <appSettings> 值用作环境变量:

    • PYTHONPATH 键的值可以自由扩展,但必须包括你的应用的根目录。
    • WSGI_HANDLER 键必须指向可从你的应用导入的 WSGI 应用。
    • WSGI_LOG 键是可选的,但建议将此键用于调试应用。
  3. 设置 web.config 文件中的 WSGI_HANDLER 条目,以适合正在使用的框架:

    • Bottle:在 app.wsgi_app 值后面添加括号,如以下示例所示。 括号是必需的,因为对象是函数而不是变量。 可以在 app.py 文件中查看语法。

      <!-- Bottle apps only -->
      <add key="WSGI_HANDLER" value="app.wsgi_app()"/>
      
    • Flask:将 WSGI_HANDLER 值更改为 <project_name>.app,其中 <project_name> 与项目名称匹配。 可通过查看 runserver.py 文件中的 from <project_name> import app 语句,找到准确的标识符。 例如,如果项目命名为 FlaskAzurePublishExample,则该条目如下所示:

      <!-- Flask apps only: Change the project name to match your app -->
      <add key="WSGI_HANDLER" value="FlaskAzurePublishExample.app"/>
      
    • Django:对于 Django 项目,需要对 web.config 文件进行两项更改。

      • WSGI_HANDLER 值更改为 django.core.wsgi.get_wsgi_application()。 对象位于 wsgi.py 文件中。

        <!-- Django apps only -->
        <add key="WSGI_HANDLER" value="django.core.wsgi.get_wsgi_application()"/>
        
      • 紧接在 WSGI_HANDLER 键的条目之后添加以下条目。 将 DjangoAzurePublishExample 值替换为项目的名称:

        <add key="DJANGO_SETTINGS_MODULE" value="django_iis_example.settings" />
        
  4. 仅限 Django 应用:在 Django 项目的 settings.py 文件中,将网站 URL 域或 IP 地址添加到 ALLOWED_HOSTS 条目。 将“1.2.3.4”替换为 URL 或 IP 地址:

    # Change the URL or IP address to your specific site
    ALLOWED_HOSTS = ['1.2.3.4']
    

    如果未将 URL 添加到数组结果,则会看到以下错误:

    DisallowedHost at / Invalid HTTP_HOST header: '\<site URL\>'. You might need to add '\<site URL\>' to ALLOWED_HOSTS.
    

当数组为空时,Django 会自动允许 'localhost''127.0.0.1' 作为主机。 如果添加生产 URL,则不会自动允许这些主机站点。 因此,可能需要保留单独的 settings.py 文件开发和生产副本,或者使用环境变量来控制运行时值。

部署到 IIS 或 Windows 虚拟机

如果项目中有正确的 web.config 文件,则可以从“解决方案资源管理器”发布到运行 IIS 的计算机。 右键单击项目,选择“发布”,然后选择 IIS、FTP 等。 在这种情况下,Visual Studio 仅将项目文件复制到服务器。 你负责所有服务器端配置。