如何部署在Ubuntu 14.04 web2py的Python应用程序与uWSGI和Nginx的

该web2py的框架是快速开发全功能的Python Web应用程序的功能强大且易于使用的工具。随着web2py的,你可以很容易地开发并通过使用管理Web UI的管理应用程序。在本指南中,我们将演示如何...

介绍

web2py框架是一个功能强大和易于使用的工具,用于快速开发全功能的Python Web应用程序。 使用web2py,您可以通过使用管理Web UI轻松开发和管理您的应用程序。

在本指南中,我们将演示如何在Ubuntu 14.04上部署web2py应用程序。 我们将使用uWSGI应用程序服务器与具有多个工作进程的应用程序交互。 在uWSGI之前,我们将在逆向代理配置中设置Nginx来处理实际的客户端连接。 这是一个比使用web2py服务器或单独的uWSGI更强大的部署策略。

先决条件和目标

为了完成这个指南,你应该有一个非root用户新鲜的Ubuntu 14.04服务器实例sudo配置权限。 你可以学习如何通过我们的运行设置此服务器初始设置指南

我们将下载web2py框架并对其进行测试,以确保默认应用程序环境正常运行。 然后,我们将下载并安装uWSGI应用程序容器,作为请求和web2py Python代码之间的接口。 我们将在这之前设置Nginx,以便它可以处理客户端连接和对uWSGI的代理请求。 我们将配置每个组件以在引导时启动,以最小化对管理干预的需要。

下载web2py框架

我们的第一步是下载实际的web2py框架。 这是保持在一个git GitHub上库,所以最好的方式来下载它与git本身。

我们可以下载和安装git通过键入从Ubuntu默认库:

sudo apt-get update
sudo apt-get install git

一旦git安装,我们可以克隆库对我们用户的主目录。 我们可以为应用程序命名我们想要的。 在我们的例子中,我们使用的是名称myapp为简单起见。 我们需要添加--recursive标志,因为数据库抽象层作为其自身的处理git子模块:

git clone --recursive https://github.com/web2py/web2py.git ~/myapp

该框架的web2py将下载到一个名为myapp你的home目录中。

我们可以通过移动到目录来测试默认应用程序:

cd ~/myapp

管理界面必须通过SSL保护,所以我们可以做一个简单的自签名证书来测试这个。 通过键入以下内容创建服务器密钥和证书:

openssl req -x509 -new -newkey rsa:4096 -days 3652 -nodes -keyout myapp.key -out myapp.crt

您将必须填写您生成的证书的一些信息。 实际上在这种情况下唯一重要的部分是Common Name字段,这应该引用您的服务器的域名或IP地址:

. . .

Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:New York
Locality Name (eg, city) []:New York City
Organization Name (eg, company) [Internet Widgits Pty Ltd]:DigitalOcean
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:server_domain_or_IP
Email Address []:admin@email.com

完成后,SSL密钥和证书应位于应用程序目录中。 这些将被调用myapp .keymyapp .crt分别。

完成后,我们可以启动web2py Web界面来测试它。 为此,我们可以键入:

python web2py.py -k myapp.key -c myapp.crt -i 0.0.0.0 -p 8000

将要求您选择管理界面的密码。

现在,您可以在网络浏览器中访问您的应用程序,方法是导航到:

https://server_domain_or_IP:8000

确保你使用https ,而不是http在上述地址。 系统将警告您的浏览器无法识别SSL证书:

web2py SSL警告

这是预期的,因为我们已经签署了我们自己的证书。 点击“高级”链接或浏览器给您的任何其他链接,然后按计划进入网站。 您将看到web2py界面:

web2py欢迎应用程序

通过单击最右边的“管理界面”按钮,您应该能够输入运行服务器时选择的密码并进入管理站点:

web2py管理界面

这使您可以访问运行应用程序的实际代码,允许您从界面本身编辑和调整文件。

当你完成环视后,在终端窗口中输入CTRL-C。 我们测试了我们的应用程序,并证明当web2py开发服务器运行时,它可以在Web上访问。

安装和配置uWSGI

现在我们有web2py应用程序可操作,我们可以配置uWSGI。 uWSGI是一个应用程序服务器,可以通过名为WSGI的标准接口与应用程序通信。 要了解更多关于这一点,阅读这部分我们的指南有关建立uWSGI和Nginx的在Ubuntu 14.04。

安装uWSGI

与上面链接的指南不同,在本教程中,我们将在全球安装uWSGI。 之前,我们可以安装uWSGI,我们需要安装pip ,Python的包管理器,以及uWSGI依赖于Python开发的文件。 我们可以直接从Ubuntu的存储库安装:

sudo apt-get install python-pip python-dev

现在,我们可以在全球范围与安装uWSGI pip键入以下命令:

sudo pip install uwsgi

uWSGI应用程序容器服务器使用WSGI接口规范与Python应用程序接口。 该web2py的框架包括旨在提供其在该界面的文件handlers目录。 要使用该文件,我们需要将它移出目录并进入主项目目录:

mv ~/myapp/handlers/wsgihandler.py ~/myapp

使用主项目目录中的WSGI处理程序,我们可以检查uWSGI是否能够通过键入以下内容来为应用程序提供服务:

uwsgi --http :8000 --chdir ~/myapp -w wsgihandler:application

这应该再次启动应用程序在端口8000.这一次,由于我们不使用SSL证书和密钥,它将通过纯HTTP而不是HTTPS。 您可以再次使用在浏览器中测试这个http协议。 您将无法测试管理界面,因为web2py在加密不可用时禁用此界面。

完成后,在终端窗口中键入CTRL-C以停止服务器。

创建uWSGI配置文件

现在我们知道uWSGI可以为应用程序提供服务,我们可以使用应用程序的信息创建一个uWSGI配置文件。

创建在目录/etc/uwsgi/sites来存储配置,然后移动到该目录:

sudo mkdir -p /etc/uwsgi/sites
cd /etc/uwsgi/sites

我们将调用我们的配置文件myapp.ini

sudo nano myapp.ini

在配置文件中,我们需要先从[uwsgi]标题下我们所有的配置指令将被放置。 在头之后,我们将指示我们的应用程序的目录路径,并告诉它模块要执行。 这将是我们在命令行上使用的相同信息。 您不需要修改模块行:

[uwsgi]
chdir = /home/user/myapp
module = wsgihandler:application

接下来,我们需要指定我们希望uWSGI在主模式下操作。 我们想产生五个工作进程:

[uwsgi]
chdir = /home/user/myapp
module = wsgihandler:application

master = true
processes = 5

接下来,我们需要指定我们想要uWSGI如何获取连接。 在我们对uWSGI服务器的测试中,我们接受了正常的HTTP连接。 但是,由于我们将在uWSGI之前配置Nginx作为反向代理,我们有其他选项。 使用Nginx的可以代理uwsgi协议,一个快速的二进制协议由uWSGI与其他服务器通信而设计的。 我们将使用此协议进行通信,这是默认的,如果我们不指定另一个协议。

由于我们使用Nginx的连通uwsgi协议中,我们并不需要的网络端口。 相反,我们将使用一个更安全,更快的Unix套接字。 我们将把它放在我们的应用程序目录中。 我们需要修改权限,以便组可以读写套接字。 稍后,我们将给予Nginx进程组所有权的套接字,以便uWSGI和Nginx可以通过套接字进行通信:

[uwsgi]
chdir = /home/user/myapp
module = wsgihandler:application

master = true
processes = 5

socket = /home/user/myapp/myapp.sock
chmod-socket = 660
vacuum = true

vacuum指令时uWSGI进程结束上述将清理套接字文件。

我们的uWSGI配置文件现已完成。 保存并关闭文件。

创建uWSGI Upstart文件

我们为uWSGI创建了一个配置文件,但是我们还没有将应用程序服务器设置为在启动时自动启动。 要实现此功能,我们可以创建一个简单的Upstart文件。 我们将告诉它以“Emperor模式”运行uWSGI,它允许应用程序服务器读取任意数量的配置并为每个配置启动服务器。

创建于文件中/etc/init目录所在的Upstart过程中寻找它的配置文件:

sudo nano /etc/init/uwsgi.conf

我们将首先给我们的服务文件一个描述,并指明我们想要自动启动它的运行级别。 传统的多用户运行级别是2,3,4和5.当服务器进入其他运行级别(例如在关机,重新引导或单用户模式时),我们将使用Upstart停止服务:

description "uWSGI application server in Emperor mode"

start on runlevel [2345]
stop on runlevel [!2345]

接下来,我们需要指定用户和组来运行进程下。 我们将使用我们的普通用户帐户,因为它拥有我们所有的项目文件。 对于我们的团队,我们需要允许www-data组所有权,这是Nginx的下运作的组。 这将允许Web服务器与uWSGI自由通信,因为我们的uWSGI配置给予套接字组读取和写入权限。

之后,我们只需要指定运行的命令来启动uWSGI。 我们只需要使用--emperor旗帜,并通过它的目录包含我们的配置文件:

description "uWSGI application server in Emperor mode"

start on runlevel [2345]
stop on runlevel [!2345]

setuid user
setgid www-data

exec /usr/local/bin/uwsgi --emperor /etc/uwsgi/sites

这将启动一个uWSGI应用程序服务器来处理我们的web2py站点。 Emperor模式允许我们在其他项目的这个目录中轻松添加配置文件。 他们将被自动处理。

我们现在完成了我们的Upstart脚本。 保存并关闭文件。 在这一点上,我们不能启动uWSGI服务,因为我们还没有安装Nginx。 这意味着我们告诉我们的脚本运行的组还不可用。

安装和配置Nginx作为反向代理

通过配置uWSGI并准备好,我们现在可以安装和配置Nginx作为我们的反向代理。 这可以从Ubuntu的默认存储库下载:

sudo apt-get install nginx

一旦Nginx安装,我们可以继续修改服务器块配置。 我们将使用默认服务器块作为基础,因为它有我们需要的大部分:

sudo nano /etc/nginx/sites-available/default

web2py应用程序检测您是使用纯HTTP还是使用SSL加密进行连接。 因此,我们的文件实际上每个都包含一个服务器块。 我们将从配置为在端口80上操作的服务器块开始。

更改server_name引用您的网站应该是访问的域名或IP地址。 然后,我们将创建一个location {}块,将匹配的静态内容的请求。 基本上,我们要使用正则表达式匹配结尾的请求/static/与前面的路径组件。 我们希望这些请求到地图applications我们的web2py项目中的目录。 请确保引用您用户的主目录和应用名称:

server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    root /usr/share/nginx/html;
    index index.html index.htm;

    server_name server_domain_or_IP;

    location ~* /(\w+)/static/ {
        root /home/user/myapp/applications/;
    }

    . . .

之后,我们需要调整location / {}块请求传递给我们的uWSGI插座。 我们只需要包括Nginx的打包uWSGI参数文件并通过要求我们配置(在我们的uWSGI插座.ini文件):

server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    root /usr/share/nginx/html;
    index index.html index.htm;

    server_name server_domain_or_IP;

    location ~* /(\w+)/static/ {
        root /home/user/myapp/applications/;
    }

    location / {
        include uwsgi_params;
        uwsgi_pass unix:/home/user/myapp/myapp.sock;
    }
}

这将是我们所需要的第一个服务器块。

在文件的底部,有一个注释掉的部分,其中包含使用SSL提供内容所需的大多数指令。 您可以识别该块,因为它已经listen 443;作为第一个指令。 取消注释此块以开始配置它。

要启动,更改server_name再次以匹配您的服务器的域名或IP地址。 然后我们就可以跳转到ssl_certificatessl_certificate_key指令。 我们将会把我们生成的SSL证书到一个目录中/etc/nginx/ssl瞬间,所以指定的路径,在该位置的文件:

server {
    listen 443;
    server_name server_domain_or_IP;

    root html;
    index index.html index.htm;

    ssl on;
    ssl_certificate /etc/nginx/ssl/myapp.crt;
    ssl_certificate_key /etc/nginx/ssl/myapp.key;

    . . .

ssl_protocols列表中,删除的SSLv3,如已发现具有在协议本身固有的弱点。

然后我们就可以跳转到location / {}块,并把我们在最后一个服务器块做了同样的uWSGI进行代理的信息:

server {
    listen 443;
    server_name server_domain_or_IP;

    root html;
    index index.html index.htm;

    ssl on;
    ssl_certificate /etc/nginx/ssl/myapp.crt;
    ssl_certificate_key /etc/nginx/ssl/myapp.key;

    ssl_session_timeout 5m;

    #ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
    ssl_prefer_server_ciphers on;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:/home/user/myapp/myapp.sock;
    }
}

您现在应该在此文件中配置了两个服务器块。 保存并在完成后关闭它。

最后步骤

接下来,我们需要将SSL证书移动到我们指定的目录。 首先创建目录:

sudo mkdir -p /etc/nginx/ssl

现在,将您创建的证书和密钥移动到该目录。 如果您有由商业证书颁发机构签名的SSL证书,则可以在此处替换证书和相应的密钥,以避免访问者的不受信任的SSL证书警告:

sudo mv ~/myapp/myapp.crt /etc/nginx/ssl
sudo mv ~/myapp/myapp.key /etc/nginx/ssl

修改权限,使非root用户无法访问该目录:

sudo chmod 700 /etc/nginx/ssl

现在,检查你的Nginx配置文件的语法错误:

sudo nginx -t

如果没有报告语法错误,我们可以继续并重新启动Nginx:

sudo service nginx restart

我们也可以开始我们的uWSGI服务:

sudo service uwsgi start

我们需要做的最后一件事是复制我们的应用程序的参数文件,以便当在端口443上提供连接时,它将被正确读取。这包含我们为管理界面配置的密码。 我们只需要将它复制到一个新的名称,指示端口443而不是端口8000:

cp ~/myapp/parameters_8000.py ~/myapp/parameters_443.py

这样,您应该能够使用服务器的域名或IP地址访问您的服务器。 使用https ,如果你想登录到管理界面。

结论

在本指南中,我们设置了一个示例web2py项目来实施部署。 我们已经将uWSGI配置为在我们的应用程序和客户端请求之间的接口。 然后我们在uWSGI前面设置Nginx,以允许SSL连接并有效地处理客户端请求。

web2py项目从一开始就提供了一个可行的Web界面,从而简化了网站和Web应用程序的开发。 通过利用本文中描述的通用工具链,您可以轻松地从单个服务器提供您创建的应用程序。