使用IIS的修改版FastCGI支持来服务WSGI应用程序。
项目描述
在IIS上以本地方式服务Python WSGI应用程序
快速入门
用户快速入门
iiswsgi 发行版包含两个示例 IIS 应用,一旦添加了自定义源,就可以通过 WebPI 安装
安装并启动 Web 平台安装程序
使用右上角的搜索框搜索 Web Matrix
点击最近一个 Web Matrix 条目旁边的“添加”,然后在右下角点击“安装”,并按照说明操作
通过点击右下角的链接打开 选项 对话框
在 自定义源 下,添加来自 iiswsgi 下载 的最新 *.webpi.xml 文件的 URL,然后点击 添加源
在 哪个 Web 服务器…? 下,选择 IIS Express,然后点击 确定
使用右上角的搜索框搜索 pyramid
点击 Pyramid 应用 旁边的“添加”,然后在右下角点击“安装”,并按照说明操作
分销商快速入门
假设有一个带有 Python 发行版和 设置脚本(使用 setuptools)以及一个 WSGI *.ini 配置文件 的 Paste,以下步骤可以用来发布到 WebPI
将 iiswsgi 安装到用于构建发布的 Python 环境中
>C:\Python27\Scripts\easy_install.exe -U iiswsgi
将以下内容复制到 dist 根目录,并根据需要进行调整
examples/pyramid.msdeploy/Manifest.xml.in
examples/pyramid.msdeploy/Parameters.xml
examples/pyramid.msdeploy/iis_install.stamp.in
examples/pyramid.msdeploy/web.config.in
将自定义设置添加到 setup.py
... from iiswsgi import install_msdeploy ... class install_custom_msdeploy(install_msdeploy.install_msdeploy): def run(self): """Perform custom tasks.""" os.environ['WEB_CONFIG_VAR'] = 'foo' self.pre_install() CUSTOM_SETUP self.post_install() ... setup( ... cmdclass=dict(install_msdeploy=install_custom_msdeploy), ...
构建一个 MSDeploy 包
>C:\Python27\python.exe setup.py bdist_msdeploy
将 WebPI 依赖项添加到 setup.py
... setup( ... extras_require=dict(install_msdeploy=['virtualenv'], webpi_eggs=['virtualenv', 'iiswsgi']), ...
将 WebPI 源元数据添加到 setup.py
有关示例,请参阅 examples/pyramid.msdeploy/setup.py
安装 Web 平台安装程序
安装 fciv.exe 以生成 SHA1 哈希值
必须放置在 %PATH% 中。推荐的位置是 %ProgramFiles%\Microsoft\Web Platform Installer,因为当 WebPI 安装时,它会放在路径中。
构建一个本地的 WebPI 源
>C:\Python27\python.exe setup.py bdist_webpi -u "{msdeploy_package_url}" -m .
本地测试
启动 Web 平台安装程序
点击右下角的 选项 链接
输入以下源 URL 并点击 添加源:file:///C:/Users/%USERNAME%/Documents/GitHub/%DIST_NAME%/dist/%DIST_NAME%-%VERSION%-py2.7-win32.webpi.xml
点击 确定 并等待 WebPI 解析源
搜索您的发行版并安装
观察 WebPI 启动 Web Matrix 并在浏览器中打开站点
上传/发布
>C:\Python27\python.exe setup.py bdist_msdeploy bdist_webpi -m . upload
如果一切正常,MSDeploy 压缩包和 WebPI 源应该上传到 PyPI。然后您可以指示用户将源添加到 WebPI,他们就可以安装您的包。
工作原理
在 IIS 上发布 WSGI 应用涉及多个步骤和组件。请参阅 Web Deploy 包内容 和 IIS WSGI 工具 部分,以获取更多技术细节。以下是流程概述和涉及的技术。
Python发行版
这是一个先决条件,并且完全不特定于IIS、MSDeploy或WebPI,只针对Python。这只是一个包含一个 setup.py 设置脚本 的目录,该脚本定义了分发和它的元数据,并且与标准的Python distutils 和 setuptools 方法几乎没有不同。换句话说, wherever possible, iiswsgi 尽可能重用 setup.py 元数据,并且当它需要新的元数据时,使用 setuptools 入口点 来添加 设置kwargs。
自定义设置
如果应用程序需要设置额外的设置,而不仅仅是设置一个 虚拟环境 和安装依赖项,这也可以通过在 setup.py 中通过继承 install_msdeploy 安装MSDeploy 命令来实现。有关详细信息,请参阅 快速入门 和 安装MSDeploy 命令。
MSDeploy软件包
Microsoft的Web Deploy工具是WebPI用来安装IIS应用程序的,并期望一个 MSDeploy包,这是一个包含一些元数据的简单zip文件。有一些 特殊文件 和三个 iiswsgi distutils 命令,这些命令有助于定义和构建一个MSDeploy包。这些命令也可以单独运行或一次性运行,只需运行最后一步,它将首先运行其他命令。单独运行它们对于调试打包问题很有用。
构建MSDeploy包 build_msdeploy 命令
安装MSDeploy install_msdeploy 命令
测试MSDeploy test_msdeploy 命令
构建MSDeploy分发 bdist_msdeploy 命令
在执行最后一个命令完成后,一个MSDeploy zip文件将出现在 dist 目录中,就像其他任何dist命令(如 sdist)一样。您也可以使用 upload 命令上传该包。
构建包的日志输出或管理详细程度与任何其他disutils/setup.py使用没有区别,输出在控制台上,可以根据需要重定向。有关详细信息,请参阅 >C:\Python27\python.exe setup.py --help。
WebPI源
Web Platform安装程序可以在其选项对话框中提供额外的源。这个源可以定义可以与它们的元数据(包括依赖项)一起安装的事情。 bdist_webpi 命令可以构建这个源作为另一个dist文件,因此也可以使用 upload 命令发布。
为了本地测试,请使用 bdist_webpi -u "{msdeploy_package_url}" 选项将feed中MSDeploy包的 file:///... 下载URL放入。然后在WebPI的选项对话框中使用feed本身的 file:///... URL,该URL将在运行 bdist_webpi 命令时打印到控制台。
当处理feed时,WebPI将日志信息记录在 %LOCALAPPDATA%\Microsoft\Web Platform Installer/logs/webpi 目录中。当调试feed问题时,只需查看该目录中最新的 webpi#.txt 文件即可。
MSDeploy软件包安装
一旦源数据被包含在WebPI中,就可以搜索和安装条目。安装后但在WebPI报告完成之前,在MSDeployManifest中的任何runCommand提供者都会运行,此时会调用iiswsgi_install.exe脚本以找到已安装的应用程序并运行distutils设置命令,默认情况下,在该发行版中运行install_msdeploy和test_msdeploy。大多数应用程序都将想要在运行设置命令之前使用iiswsgi_install.exe -e选项来设置一个虚拟环境。有关更多详细信息和建议,请参阅MSDeployManifest和install_msdeploy。
在安装过程中,WebPI和MSDeploy将日志输出到%LOCALAPPDATA%\Microsoft\Web Platform Installer\logs\install。在调试安装问题时,只需查看该目录中最近修改的日期戳目录中的App Title.txt文件。可以通过在您的Manifest.xml的<runCommand path=...属性中添加iiswsgi_install.exe -v选项来控制详细程度。在安装错误后,在已安装的应用程序中运行install_msdeploy命令来进一步调试也是很有价值的。
IIS托管
如果安装已完成,全局IIS配置中会有一个<fastCgi><application...,应用web.config中的一个相应的处理程序,当收到对应用程序的请求时,IIS将调用指定的处理程序。对于iiswsgi,处理程序将是一个使用egg:iiswsgi#iis FCGI服务器的
IIS在启动时吞咽所有FCGI进程输出,如果有任何错误启动,这会使启动问题难以调试。第一步应该是手动调用web.config中的<application...元素的fullPath和arguments属性中的FCGI进程。如果这样做不能重现错误,egg:iiswsgi#iis FCGI服务器在启动时会尽量保守,以确保输出记录在某个地方。请检查以下位置以获取输出
%IIS_USER_HOME%\Logs\%IISEXPRESS_SITENAME%\iiswsgi.log
%IIS_USER_HOME%\Logs\iiswsgi.log
%TEMP%\iiswsgi.log
\iiswsgi.log
详细程度可以通过将paster serve -v...选项给PasteScript在web.config.in模板中控制。
Web Deploy软件包内容
发布Python Web应用程序的MSDeploy包的开发人员通过以下Python发行版中的文件与iiswsgi交互。除了这些文件外,使用
设置脚本
与其他Python构建、分发和安装任务一样,setup.py脚本用于控制如何构建MSDeploy包、分发什么以及如何安装。
Python清单
使用 Python 的源代码分发 MANIFEST.in 模板格式来声明包中包含的内容。
MSDeploy清单
使用 Manifest.xml.in 模板生成 Web Deploy 清单。当使用 iiswsgi 时,它包含一个 runCommand 提供者,该提供者调用 iswsgi_install.exe 的 MSDeploy 安装引导脚本。大多数包都希望通过向 iiswsgi_install.exe 包含 -e 选项来安装到 virtualenv 中。
可以使用 build_msdeploy 命令将 runCommand 选项属性 写入 MSDeploy 在安装过程中处理清单时使用的哈希中。大多数应用程序都希望包括 successReturnCodes="0x0" 属性,以确保命令失败时向用户报告。许多应用程序还希望调整 waitAttempts="5" 和/或 waitInterval="1000" 属性,以给命令足够的时间完成。
MSDeploy参数
Parameters.xml 文件定义了 WebPI 在安装时提示用户输入的参数。有关使用参数影响自定义设置的示例,请参阅 examples/pyramid.msdeploy/Parameters.xml。
IIS Web配置
使用 web.config.in 模板生成 IIS 站点配置文件。当使用 iiswsgi 时,它包含一个调用 egg:iiswsgi#iis 的 iiswsgi FCGI 网关 的 fastCgi 应用程序。大多数包都希望调整控制进程行为的 <application… 属性。这也是指定运行 WSGI 应用程序的 *.ini 配置文件或 app_factory 入口点 的位置。
IIS安装戳记文件
将 iis_install.stamp.in 模板复制到位置,作为由 iiswsgi_install.exe 的 MSDeploy 安装引导脚本 在安装时查找正确的 APPL_PHYSICAL_PATH 的 iis_install.stamp 标记文件使用。
设置配置
如果您的 Setup 脚本 没有使用 setuptools,则需要 setup.cfg 文件。换句话说,在 setuptools 下,如果已安装 iiswsgi,则命令将自动可用,无需此文件。在没有 setuptools 的情况下,使用以下内容使 iiswsgi distutils 命令对您的包可用
[global] command_packages = iiswsgi
IIS WSGI工具
iiswsgi 的组成部分如下
iiswsgi FCGI网关
《egg:iiswsgi#iis》paste.server_runner 或 paste.server_factory 是 FastCGI 到 WSGI 的网关。IIS 通过 PasteScript 的 paster 脚本,使用 PasteDeploy INI 配置文件 来启动一个 Python WSGI 应用程序,作为 FastCGI 进程。告诉 paster 使用 IIS FCGI 网关,通过 paster.exe serve -s "egg:iiswsgi#iis" ... 或在 PasteDeploy INI 配置文件 中进行设置。
[server:iis] use = egg:iiswsgi#iis
这与 distutils 命令本身无关,如果项目需要,可以独立使用。
IIS 对 FastCGI 协议的实现并不完全符合标准。最显著的是,在 STDIN_FILENO 中传递的不是打开套接字的句柄,而是一个 Windows 命名管道。这个命名管道不支持类似于套接字的行为,至少在 Python 中是这样。因此,egg:iiswsgi#iis 网关扩展了 flup 的 WSGI 到 FCGI 网关,以支持使用两次打开的 STDIN_FILENO,每次分别近似 FastCGI 中指定的套接字的 recv 和 send 端。
构建MSDeploy软件包
《build_msdeploy》distutils 命令编译 MSDeploy 的 Manifest.xml 文件,将任何 runCommand 属性转换为必要的散列。它还会将 IIS 安装戳记文件 iis_install.stamp 复制到 MSDeploy 安装引导 的 iiswsgi_install.exe 脚本,以便在安装时找到正确的 APPL_PHYSICAL_PATH。
安装MSDeploy
《install_msdeploy》distutils 命令执行在 IIS 上部署 Python Web 应用程序所需的一些常见操作:安装依赖项、在 web.config 中进行变量替换,并将 FastCGI 应用程序安装到 IIS 的全局配置中。
由于大多数应用程序都需要在 web.config 文件中包含路径或参数特定的部分,因此 install_msdeploy 命令将在将 web.config.in 模板写入 web.config 时执行变量替换。要添加变量到替换中,只需使用 自定义设置 将它们放入 os.environ 中,然后再调用基类的 run() 方法。
由于 <fastCgi><application... 元素在 web.config 中不起作用,因此 install_msdeploy 命令将使用。以下是一个示例,仅供参考或调试:
> appcmd.exe set config -section:system.webServer/fastCgi /+"[fullPath='%SystemDrive%\Python27\python.exe',arguments='-u %SystemDrive%\Python27\Scripts\iiswsgi-script.py -c %HOMEDRIVE%%HOMEPATH%\Documents\My Web Sites\FooApp\test.ini',maxInstances='%NUMBER_OF_PROCESSORS%',monitorChangesTo='C:\Users\Administrator\Documents\My Web Sites\FooApp\test.ini']" /commit:apphost
请参阅 IIS FastCGI 参考 了解如何配置 IIS 以支持 FastCGI 的更多详细信息。请注意,您不能在 monitorChangesTo 参数中使用环境变量,否则 IIS 将返回一个模糊的 500 错误。
这里也是通过继承 setup.py 中的 Install MSDeploy 命令来 自定义设置 的地方。使用 distutils 的 cmdclass 关键字参数来调用 setup()。查看 快速入门 获取一个小示例,或者查看 examples\pyramid.msdeploy\setup.py 获取一个工作示例。
测试MSDeploy
test_msdeploy distutils 命令使用 paster 请求 和一个 PasteDeploy INI 配置文件 来模拟向应用程序发送请求。如果失败,则命令失败,这在运行 MSDeploy 软件包安装 时非常有用,以确保用户在安装成功的情况下也能在 WebPI 中看到错误。更多信息请参阅 >C:\Python27\python.exe setup.py test_msdeploy --help。
构建MSDeploy发行版
bdist_msdeploy distutils 命令组装一个实际的 MSDeploy 软件包:它首先运行 build_msdeploy 构建 MSDeploy 软件包 命令。然后运行 install_msdeploy 安装 MSDeploy 命令,以防软件包需要安装过程中的任何结果并测试安装过程。最后,它创建一个 MSDeploy 软件包 压缩文件,该文件的内容由与 distutils 为 sdist 发行版提供的相同工具控制,包括 MANIFEST.in。
MSDeploy安装引导
iiswsgi_install.exe 脚本初始化 MSDeploy 软件包安装过程,可选地首先设置虚拟环境。它找到正确的 APPL_PHYSICAL_PATH,更改到该目录,并使用参数调用 设置脚本。
这个控制台脚本试图解决 WebPI 和 MSDeploy 没有为正在安装的应用程序提供任何上下文的事实。具体来说,当在 Manifest.xml 中使用 runCommand MSDeploy 提供者时,由 runCommand 启动的进程无法知道它在安装时调用的应用程序:不是当前工作目录,不是参数,也不是任何环境变量。
因此,这个脚本必须在调用它的 设置脚本 之前搜索应用程序。它使用 appcmd.exe 查找虚拟目录,这些目录的站点与应用程序名称匹配,并且包含仍在那里的标记文件。更多信息请参阅 >Scripts\iiswsgi_install.exe --help。
构建WebPI源发行版
bdist_webpi distutils 命令从一个或多个具有依赖关系的 MSDeploy 软件包中组装 WebPI 提供程序。要包含的 MSDeploy 软件包由通过 --msdeploy-bdists 命令选项传递的路径定义,这些路径具有 setup.py 文件,其 MSDeploy 软件包的 dist 压缩文件之前已构建,使用 shlex.split 分隔。MSDeploy 压缩文件的下载 URL 通过使用 Python 字符串.format() 来扩展 msdeploy_url_template setup() 关键字参数来确定。
全局源数据来自运行命令的发行版。会将指定在 --msdeploy-bdists 命令选项中的发行版和 webpi_eggs 依赖项在 extras_require 中添加到源。WebPI 依赖项和相关产品来自 install_msdeploy 和 install_webpi 的 setup() kwargs 所提供的列表。这些条目的元数据来自相应的发行版。以下是在定义了给定发行版的情况下,源中使用的附加 setup() kwargs
标题
作者网址
许可网址
显示网址
帮助网址
发布
图标网址
屏幕截图网址
发现文件
清理WebPI缓存
clean_webpi distutils 命令会清除一个或多个 MSDeploy 软件包下载和源本身的 WebPI 缓存。要从缓存中清除的 MSDeploy 软件包来自相同的 --msdeploy-bdists 命令选项。
调试
iiswsgi 的重要目标之一是使与 IIS 集成的过程更加透明和可洞察。在非 Windows/UNIX 世界中,对于开发者来说,在 Windows 上开发和部署通常比在其他任何操作系统上更加脆弱和不透明。以下是一些 iiswsgi 尝试解决这一问题的方法。
- 在非 Windows 上的优雅降级
首先,iiswsgi 尝试在非 Windows 平台上优雅降级。具体来说,当某些可执行文件、环境变量或其他特定于 Windows 的环境组件缺失时,iiswsgi 操作不会引发异常,而只会记录错误。这允许在 NIX 平台上开发,并在一定程度上测试 MSDeploy 软件包。这一副作用是,当在 Windows 上运行时,`distutils`_ 命令的输出中包含大量控制台输出时,可能会错过一些错误,所以请仔细检查您的输出。
- 日志记录
当进程的某个部分失败时,在 Windows 上查找有关出错信息可能比在其他平台上困难得多。请参阅 How it Works 部分了解查找每个部分过程日志文件的地址。
已知问题
- IIS 下无法启动 FCGI 进程
示例应用可以很好地部署到 IISExpress/Web Matrix,但当切换到完整的 IIS 时,它会报告 FCGI 进程提前退出。即使在脚本的最顶部进行文件写入后跟随 flush() 和 fsync(),文件中仍然没有内容。因此,似乎 IIS 永远没有真正启动进程。如果有人可以测试这一点并提供一些见解,将非常感激。
- 无法在 runCommand 提供器中访问 APPL_PHYSICAL_PATH
当前搜索方法太脆弱了,如果 MSDeploy 或 WebPI 为 runCommand 设置 APPL_PHYSICAL_PATH 环境变量,将大为改观。拥有 MS 支持合同的任何人,请提交关于此问题的请求。
- <fastCgi><application> 在 web.config 中不起作用
应该可以在 web.config 文件中注册 FCGI 应用程序,但这不起作用。因此,install_msdeploy 通过读取 web.config 并使用 AppCmd.exe 来执行实际的 FCGI 应用程序安装来解决这个问题。如果 web.config 能够像预期的那样工作,那就更好了。任何有 MS 支持合同的,请提交有关此问题的请求。
- System.IO.FileNotFoundException: 无法找到文件 '\\?\C:\...
我在 Windows 7 上遇到这个错误,在两台不同的机器和多次安装上,一个是 OEM,另一个是纯净的 Windows 7 Extreme。当这种情况发生时,这似乎是在运行“Web 平台安装程序”,然后退出,然后再次运行(在之间没有重启机器)时发生的。为了解决这个问题,你可能需要重启机器。有关更多信息,请参阅 stack overflow 问题 MS WebPI 包在 Manifest.xml 中 runCommand 不工作。因此,不建议退出并重新启动 WebPI。因此,在 WebPI 中使内容更改生效的最佳方法可能是
单击 WebPI 右下角的 选项 链接
单击你的源旁边的 X 以删除它
单击 确定 并等待 WebPI 完成剩余源更新
运行 iiswsgi_webpi.exe
再次在 WebPI 中单击底部的 选项 链接
输入源 URL 并单击 添加源 以恢复源
单击 确定 并等待 WebPI
现在你的源更改应该已在 WebPI 中反映出来。
- System.IO.FileNotFoundException: 无法加载文件或程序集
当使用 WebPI 在全 IIS 上安装时,即当不使用 IIS Express 和 Web Matrix 时,会发生此错误。可以通过在 WebPI 中安装“WebDeploy 工具”来解决。bdist_webpi 命令通过将其添加为所有 MSDeploy 包的依赖项来解决此问题。以下是日志中的错误
DownloadManager Error: 0 : System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Web.Deployment, Version=9.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified. File name: 'Microsoft.Web.Deployment, Version=9.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' at Microsoft.Web.PlatformInstaller.MSDeployProxy.GetDeclaredParameters() at Microsoft.Web.PlatformInstaller.MSDeployPackage.get_DeclaredParameters() at Microsoft.Web.PlatformInstaller.UI.AppSitePage.GetApplicationName(MSDeployPackage package, String& appName) at Microsoft.Web.PlatformInstaller.UI.AppSitePage.InitializeComponent()
- 检索远程组件 CLSID 2b72133b-3f5b-4602-8952-803546CE3344 的 COM 类工厂错误 80040154
当使用 WebPI 在全 IIS 上安装时,即当不使用 IIS Express 和 Web Matrix 时,会发生此错误。可以通过在 WebPI 依赖项中安装“IIS 管理控制台”来解决
- WebPI 错误可能被隐藏
有时,WebPI 可能将错误消息隐藏在 WebPI 窗口后面。因此,如果 WebPI 已挂起很长时间,请尝试使用 Alt-TAB 查看是否有隐藏在 WebPI 窗口后面的错误窗口。
- WebPI 获取缓存的源和 MSDeploy 包
尽管有 clean_webpi 辅助工具和手动清除 %LOCALAPPDATA%\Microsoft\Web Platform Installer 下的所有缓存,但 WebPI 仍然有几次获取了过时内容,导致对源中的 SHA1 进行验证错误和其他问题。当这种情况发生时,一种可能的解决方案是使用 IE 下载过时的 WebPI 资源。
更新日志
0.3 - 2012-10-29
将服务器转换为粘贴服务器
使用 distutils/setuptools 命令进行构建和安装过程
0.2 - 2012-10-13
自定义构建脚本方法
0.1 - 未知
初始发布