如何在Nginx反向代理后面部署CherryPyWeb应用程序
介绍
CherryPy 是一个出色的框架,可用于创建各种规模的 Web 应用程序和 API – 从“Python 入门”Hello, world! 到可以成为世界级的最繁忙的网站之一!
如果您来自不同的语言,那么当您第一次开始使用 CherryPy 进行开发时,让您的新应用程序上线的过程可能会显得有点陌生。
在这篇 DigitalOcean 文章中,我们将介绍两种部署绝对可靠的基于 CherryPy 的 Web 应用程序以及使用 pip 管理其依赖项的好方法。
词汇表
1. CherryPy 和 Web 应用程序部署简介
- Web 应用程序部署
- WSGI
- 使用 Nginx 作为反向代理
- Python (WSGI) Web 应用程序服务器
- CherryPy 的应用程序(HTTP)服务器简介
- uWSGI
2. 准备一个暴露“app”对象的简单 CherryPy 应用程序
- 创建应用程序结构
- 使用 nano 编辑“app/init.py”
- 使用 nano 编辑“wsgi.py”
3. 为 CherryPy 部署准备系统
- 更新系统
- 设置 Python、pip 和 virtualenv
- 蟒蛇开发
- 点子
- 虚拟环境
- 下载和安装 CherryPy
- 下载和安装uWSGI
4. 如何使用 pip 处理应用程序依赖项
- 创建应用程序依赖项列表
- 从应用程序依赖项列表下载
5. 开始部署:下载、安装和设置 Nginx
- 安装 Nginx
- 配置 Nginx
6. 设置 Python WSGI Web 应用程序服务器
- 使用 CherryPy 自己的 Web 服务器为应用程序提供服务 [*]
- 运行和管理 CherryPy 应用服务器
- 使用 uWSGI 服务应用程序 [*]
- 运行服务器
CherryPy 和 Web 应用程序部署简介
CherryPy 作为一个整体是一个极简的 Python Web 应用程序开发框架,它没有提供太多开箱即用的组件,无论你是否想要它们。 该框架处理您可能需要的所有核心必需品(例如 会话、缓存、文件上传等),剩下的——以及选择——由 你 决定使用什么以及如何使用。 它将自己与其他 Python 框架区分开来,它使用随附的、准备部署 HTTP/1.1 兼容、WSGI 线程池 Web 服务器 的简单性来上网。
Web 应用程序部署
对于所有 Python WSGI Web 应用程序,部署包括准备一个 WSGI 模块,该模块包含对您的应用程序对象的引用,然后 Web 服务器将其用作传递请求的入口点。
注意: 但是,如果使用CherryPy自己的服务器,过程会变得更简单,你不需要特别担心。
在我们的文章中,我们将看到两种不同的应用程序部署方式:
- 使用 CherryPy 的默认网络服务器,非常适合大多数应用程序,并且;
- 为需要深入配置能力的应用程序使用另一个替代应用程序服务器 (uWSGI)。
WSGI
简而言之,WSGI 是 Web 服务器和应用程序本身之间的接口。 它的存在是为了确保各种服务器和应用程序(框架)之间以标准化的方式相互工作,在必要时允许互换(即 从开发环境切换到生产环境),这是当今的必备需求。
注意:如果您有兴趣了解更多关于WSGI和Python Web服务器的知识,请查看我们的文章:基于Python的Web服务器比较网络应用程序。
使用 Nginx 作为反向代理
Nginx 是一个非常高性能的 Web 服务器/(反向)代理。 由于重量轻、相对容易使用和易于扩展(使用附加组件/插件),它已经流行起来。 由于其架构,它能够处理 很多 的请求(几乎无限制),这取决于您的应用程序或网站负载 - 使用其他一些较旧的替代方案可能真的很难解决。
记住:“处理”连接在技术上意味着不丢弃它们并且能够使用某物为它们服务。 您仍然需要您的应用程序和数据库运行良好才能让 Nginx 为客户端 响应 而不是错误消息。
Python (WSGI) Web 应用程序服务器
Python Web 应用服务器 [通常] 要么是独立的基于 C 的解决方案,要么是完全(或部分)基于 Python(即 纯Python)的。
它们通过接受一个 Python 模块进行操作,该模块包含 - 如前所述 - 一个可调用的应用程序 包含 网络应用程序并在网络上提供它。
虽然其中一些是可以直接使用的高能力服务器,但是前面提到的原因还是推荐使用Nginx(例如 更高的性能)。 同样,通常附带 Web 应用程序框架的开发服务器不建议在生产中使用,因为它们缺乏功能 - 当然也有少数例外 !
一些流行的 Python WSGI Web 服务器是:
- 樱桃派
- 独角兽
- uWSGI
- 女服务员
CherryPy 的应用程序(HTTP)服务器简介
CherryPy 的纯 Python Web 服务器是一个紧凑的解决方案,它带有同名框架。 [CherryPy] 项目将其定义为“高速、生产就绪、线程池、通用 HTTP 服务器”,它是一个模块化组件,可用于服务 any Python WSGI Web 应用程序。
CherryPy Web 服务器的亮点:
- 一个非常紧凑且易于使用的纯 Python 解决方案
- 易于配置,易于使用
- 线程池和快速
- 允许缩放
- 支持 SSL
uWSGI
以下是上述 DigitalOcean Python 服务器比较 文章的摘录。
尽管命名约定非常混乱,uWSGI 本身是一个包含许多组件的庞大项目,旨在为构建 托管服务 提供完整的软件堆栈。 这些组件之一,uWSGI 服务器,运行 Python WSGI 应用程序。 它能够使用各种协议,包括它自己的uwsgi 有线协议,它与SCGI 准相同。 为了满足在应用程序服务器前使用独立 HTTP 服务器的可理解需求,NGINX 和 Cherokee Web 服务器被模块化以支持 uWSGI [自己的] 性能最佳的 uwsgi 协议,以直接控制其进程。
uWSGI 亮点
- uWSGI 带有一个 WSGI 适配器,它完全支持在 WSGI 上运行的 Python 应用程序。
- 它与 libpython 链接。 它在启动时加载应用程序代码,并充当 Python 解释器。 它解析传入的请求并调用 Python 可调用对象。
- 它直接支持流行的 NGINX Web 服务器(以及 Cherokee* 和 lighttpd)。
- 它是用 C 编写的。
- 它的各种组件可以做的不仅仅是运行一个应用程序,这对于扩展来说可能很方便。
- 目前(截至 2013 年底),它正在积极开发并具有快速的发布周期。
- 它具有用于运行应用程序(异步和同步)的各种引擎。
- 这可能意味着运行时内存占用更少。
准备一个暴露“app”对象的简单 CherryPy 应用程序
让我们从创建一个新的 CherryPy 应用程序作为示例开始我们的部署示例。
注意: 这里的应用示例使用虚拟环境来管理应用文件及其依赖关系。 要了解 pip 和 virtualenv,请查看我们的教程 常用 Python 工具:使用 virtualenv、使用 Pip 安装和管理包。
创建应用程序结构
我们希望使用一个简单的示例,该示例应该类似于一个非常简约但实际的应用程序。
为此,我们可以创建类似的东西:
myy_app |-- wsgi.py |__ /app |-- __init__.py
首先,让我们创建一个应用程序文件夹和一个应用程序模块:
mkdir ~/my_app mkdir ~/my_app/app
然后,让我们创建应用程序文件和部署所需的 wsgi.py
文件:
touch ~/my_app/wsgi.py touch ~/my_app/app/__init__.py
使用 nano 编辑“app/init.py”
我们创建了 app
包来包含我们的示例应用程序模块。 我们现在可以编辑 __init__.py
来定义它。
nano ~/my_app/app/__init__.py
复制并粘贴以下脚本:
import cherrypy class Root(object): @cherrypy.expose def index(self): return "Hello, world!"
按 CTRL+X 并用 Y 确认保存并退出。
使用 nano 编辑“wsgi.py”
wsgi.py
文件将用于 公开 应用程序的入口点。 在我们的示例中,在此文件中,我们将导入应用程序模块(app)并使用 CherryPy 的 WSGI Web 服务器直接运行它,或者将其传递给包含它并运行的 uWSGI。
nano ~/my_app/wsgi.py
复制并粘贴以下内容:
import cherrypy from app import Root app = cherrypy.tree.mount(Root(), '/') if __name__=='__main__': cherrypy.config.update({ 'server.socket_host': '127.0.0.1', 'server.socket_port': 8080, }) # Run the application using CherryPy's HTTP Web Server cherrypy.quickstart(Root())
按 CTRL+X 并用 Y 确认保存并退出。
为 CherryPy 部署准备系统
更新系统
为了拥有稳定的部署服务器,保持最新状态和良好维护是至关重要的。
为确保我们拥有最新可用版本的默认应用程序,我们需要更新我们的系统。
对于基于 Debian 的系统(即 Ubuntu、Debian),运行以下命令:
aptitude update aptitude -y upgrade
对于基于 RHEL 的系统(即 CentOS),运行以下命令:
yum -y update
设置 Python、pip 和 virtualenv
CentOS / RHEL 用户注意事项:
CentOS / RHEL,默认情况下,作为一个非常精简的服务器。 它的工具集很可能已经过时以满足您的需求, 不是 用于运行您的应用程序,而是为服务器的系统工具(例如 百胜)。
为了准备你的 CentOS 系统,需要设置 Python(即 从源代码编译)和 pip* / virtualenv 需要使用该解释器进行安装。
了解 如何在 CentOS 6.4 和 5.8 上使用 pip 和 virtualenv 设置 Python 2.7.6 和 3.3.3,请参考:[X144X ]如何在 CentOS 上设置 Python 2.7.6 和 3.3.3。
在 Ubuntu 和 Debian 上,默认提供最新版本的 Python 解释器,您可以使用它。 它使我们只需要安装有限数量的附加软件包:
- python-dev(开发工具),
- pip(管理包),
- virtualenv(创建隔离的、虚拟的
注意: 在继续安装某些应用程序之前,尤其是从源代码构建时,您可能需要使用以下命令安装必要的开发工具 build-essential:
aptitude install -y build-essential
蟒蛇开发
python-dev 是一个操作系统级别的包,其中包含用于构建 Python 模块的扩展开发工具。
运行以下命令以使用 aptitude 安装 python-dev:
aptitude install -y python-dev # You might need python2.7-dev # aptitude install -y python2.7-dev
点子
pip 是一个包管理器,它将帮助我们安装我们需要的应用程序包。
运行以下命令安装 pip:
curl https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py | python - curl https://raw.github.com/pypa/pip/master/contrib/get-pip.py | python - export PATH="/usr/local/bin:$PATH"
您可能需要 sudo 权限。
虚拟环境
最好在自己的 环境 中包含 Python 应用程序及其所有依赖项。 可以将环境最好(简单地说)描述为所有内容所在的隔离位置(目录)。 为此,使用了一个名为 virtualenv 的工具。
运行以下命令以使用 pip 安装 virtualenv:
sudo pip install virtualenv
下载和安装 CherryPy
可以使用 pip 包管理器安装 CherryPy 框架。
运行以下命令以使用 pip 安装 cherrypy:
# Install CherryPy Framework and HTTP Web-Server pip install cherrypy
下载和安装uWSGI
将所有与应用程序相关的元素尽可能多地包含在虚拟环境中始终是推荐的方式。 所以我们将下载并安装uWSGI。
如果你是 not 在环境中工作,uWSGI 将被全局安装(即 全系统可用)。 不建议这样做——总是选择使用 virtualenv。
要使用 pip 安装 uWSGI,请运行以下命令:
pip install uwsgi
如何使用 pip 处理应用程序依赖项
由于您很可能已经在本地计算机上开始了开发过程,因此在部署应用程序时,您需要确保已安装其所有依赖项(在您的*虚拟环境中)。
创建应用程序依赖项列表
获取对生产环境的依赖关系的最简单方法是使用 pip。 使用单个命令,它能够生成您已安装的所有包(或依赖项)(在您的 激活 环境中,如果没有,则在您的系统上 globally)并再次使用单个命令,它允许您将它们全部下载并安装。
注意: 此部分包含要在本地开发机器上执行的信息,或者从您要生成应用程序依赖项列表的任何位置执行的信息。 该文件应放置在您的应用程序目录中并上传到您的服务器。
使用“pip”创建已安装包的列表:
pip freeze > requirements.txt
此命令将创建一个名为 requirements.txt
的文件,其中包含所有已安装软件包的列表。 如果你在 virtualenv 中运行它,列表将包含安装在环境 only 中的包。 否则,将列出全局安装的所有软件包。
从应用程序依赖项列表下载
使用 pip 从列表中安装软件包:
注意: 这部分包含要在您的产品中执行的信息(即 部署)机器/环境。
pip install -r requirements.txt
此命令将下载并安装所有列出的软件包。 如果您在激活的环境中工作,文件将在那里下载。 否则,它们将被全局安装 - 这是 而不是 推荐的方式,原因在前几节中解释。
开始部署:下载、安装和设置 Nginx
无论选择哪种服务器,我们的 CherryPy 应用程序都将在 Nginx 后面上线,原因我们在前面几节中已经提到。 因此,让我们先下载和配置 Nginx,然后继续使用应用程序服务器。
基本服务器架构示例:
Client Request ----> Nginx (Reverse-Proxy) | /|\ | | `-> App. Server I. 127.0.0.1:8080 # Our example | `--> App. Server II. 127.0.0.1:8082 `----> App. Server III. 127.0.0.1:8083
安装 Nginx
CentOS / RHEL 用户注意事项:
以下说明不适用于 CentOS 系统。 请在此处 参阅 CentOS 的说明 。
运行以下命令以使用 aptitude 安装 Nginx:
sudo aptitude install nginx
要运行 Nginx,请使用以下命令:
sudo service nginx start
要停止 Nginx,请使用以下命令:
sudo service nginx stop
要重新启动 Nginx,请使用以下命令:
# After each time you reconfigure Nginx, a restart # or reload is needed for the new settings to come # into effect. sudo service nginx restart
注意:想了解更多关于Ubuntu上的Nginx,请参考我们的文章:如何在Ubuntu 12.04上安装Nginx。
配置 Nginx
注意: 下面是使用 Nginx 作为反向代理的简短教程。 要了解有关 Nginx 的更多信息,请查看 如何在 VPS 上配置 Nginx Web 服务器。
在选择并设置了一个 web 服务器来运行我们的应用程序之后,我们可以继续对 Nginx 做同样的事情,并准备好它与后端服务器 [运行 WSGI 应用程序] 对话。
为此,我们需要修改 Nginx 的配置文件:nginx.conf
运行以下命令打开 nginx.conf
并使用 nano 文本编辑器进行编辑:
sudo nano /etc/nginx/nginx.conf
您可以使用以下示例配置替换该文件,以使 Nginx 作为反向代理工作,与您的应用程序对话。
复制并粘贴以下示例配置:
worker_processes 1; events { worker_connections 1024; } http { sendfile on; gzip on; gzip_http_version 1.0; gzip_proxied any; gzip_min_length 500; gzip_disable "MSIE [1-6]\."; gzip_types text/plain text/xml text/css text/comma-separated-values text/javascript application/x-javascript application/atom+xml; # Configuration containing list of application servers upstream app_servers { server 127.0.0.1:8080; # server 127.0.0.1:8081; # .. # . } # Configuration for Nginx server { # Running port listen 80; # Settings to serve static files location ^~ /static/ { # Example: # root /full/path/to/application/static/file/dir; root /app/static/; } # Serve a static file (ex. favico) # outside /static directory location = /favico.ico { root /app/favico.ico; } # Proxy connections to the application servers # app_servers location / { proxy_pass http://app_servers; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $server_name; } } }
完成修改配置后,按 CTRL+X 并按 Y 确认保存并退出。 您需要重新启动 Nginx 才能使更改生效。
运行以下命令重启 Nginx:
sudo service nginx stop sudo service nginx start
设置 Python WSGI Web 应用程序服务器
在创建了一个示例应用程序并完成了管理依赖项之后,我们准备开始部署的最后一个阶段:设置服务器。
如上所述,在本文中,我们将重点介绍在 Nginx 后面使用 CherryPy 和 uWSGI Web 应用服务器。
使用 CherryPy 自己的 Web 服务器为应用程序提供服务 [*]
CherryPy 的纯 Python Web 服务器是框架附带的紧凑型解决方案。 该项目将其定义为“高速、生产就绪、线程池、通用 HTTP 服务器”。
由于我们是使用该框架开发的,因此我们在 wsgi.py
中的程序已经准备好在运行时开始提供服务。
我们对 CherryPy 的设置与 Nginx 的配置相匹配:
# .. cherrypy.config.update({ 'server.socket_host': '127.0.0.1', 'server.socket_port': 8080, }) # ..
运行和管理 CherryPy 应用服务器
要开始为您的应用程序提供服务,您只需使用 Python 安装执行 server.py
。
运行以下命令以按照配置启动服务器:
python ~/my_app/wsgi.py
这将在前台运行服务器。 如果您想停止它,请按 CTRL+C。
要在后台运行服务器,请使用以下命令:
python ~/my_app/wsgi.py &
当您在后台运行应用程序时,您将需要使用进程管理器(例如 htop) 杀死(或停止)它。
使用 uWSGI 服务应用程序 [*]
尽管 CherryPy 自己的 HTTP 服务器非常有能力和强大,但它并不适用于所有设置或部署。 如果您需要能够调整很多选项以匹配您所需的配置设置,那么 uWSGI 可能是您的解决方案。
运行服务器
由于它的灵活性,uWSGI 有很多选项和配置以及许多可能的使用方式。 在不让事情从一开始就复杂化的情况下,我们将尽可能简单地使用它,然后继续使用更高级的方法。
注意:在执行以下命令之前,请确保在my_app
文件夹中,否则uwsgi将无法找到wsgi.py
,也无法导入应用程序对象app。
简单的使用示例:
uwsgi [option] [option 2] .. -w [wsgi file with app. callable]
要运行 uWSGI 以从 wsgi.py 开始为应用程序提供服务,请运行以下命令:
uwsgi --socket 127.0.0.1:8080 --protocol=http -w wsgi:app
这将在前台运行服务器。 如果您想停止它,请按 CTRL+C。
要在后台运行服务器,请运行以下命令:
uwsgi --socket 127.0.0.1:8080 --protocol=http -w wsgi:app &
当您在后台运行应用程序时,您将需要使用进程管理器(例如 htop) 杀死(或停止)它。 有关详细信息,请参阅以下部分。
就是这样! 将您的应用程序服务器与 Nginx 连接后,您现在可以使用您喜欢的浏览器访问您的 Droplet 的 IP 地址来访问它。
http://[your droplet's IP adde.]/ # Hello, world!
延伸阅读
如果您想了解有关 Python Web 应用程序部署的更多信息,建议您查看我们关于该主题的以下文章以获得更好的总体理解: