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

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

介绍

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

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

先决条件和目标

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

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

下载web2py框架

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

我们可以下载和安装git通过键入从默认的CentOS软件库:

sudo yum 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开发的文件。 我们还需要一个编译器来构建实际的二进制。 为了得到pip ,我们将不得不使用EPEL资源库,其中包含额外的软件包。

我们可以通过键入以下内容激活EPEL存储库:

sudo yum install epel-release

之后,我们可以通过键入安装我们需要的包

sudo yum install python-devel python-pip gcc

现在,我们可以在全球范围与安装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作为反向代理,我们有其他选项。

而不是使用网络端口,因为所有组件都在单个服务器上运行,我们可以使用Unix套接字。 这更安全,并提供更好的性能。 这种插座将不会使用HTTP,而是将实施uWSGI的uwsgi协议,它是一种快速二进制协议设计用于与其他服务器进行通信。 Nginx的可以本地代理使用uwsgi协议,所以这是我们最好的选择。

我们需要将运行进程的用户设置为我们自己的用户,因为我们拥有这些文件。 我们还将修改套接字的权限和所有权,因为我们将给予Web服务器写访问权限。 本身将被置于内的插座/run/uwsgi目录(我们将创建一个有点这个目录),其中既uWSGI和Nginx的可以达到它。 我们将设置vacuum选项,以便在服务停止时套接字文件将自动清除:

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

master = true
processes = 5

uid = user
socket = /run/uwsgi/myapp.sock
chown-socket = user:nginx
chmod-socket = 660
vacuum = true

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

为uWSGI创建Systemd单元文件

我们为uWSGI创建了一个配置文件,但是我们还没有将应用程序服务器设置为在启动时自动启动。 为了实现这个功能,我们可以创建一个Systemd单元文件。

我们将在创建单元文件/etc/systemd/system ,其中用户创建单元文件保存的目录。 我们将调用我们的文件uwsgi.service

sudo nano /etc/systemd/system/uwsgi.service

先从[Unit]部分,它是用来指定的元数据。 我们将在这里简单地描述我们的服务:

[Unit]
Description=uWSGI Emperor service

接下来,我们将打开[Service]部分。 我们将使用ExecStartPre指令来设置我们运行服务器所需的部分。 这将确保/ run / uwsgi目录被创建,并且我们的普通用户拥有它作为组所有者的Nginx组。 带-p标志的mkdir和chown命令都将成功返回,即使它们已经存在。 这是我们想要的。

对于由ExecStart指令指定的实际启动命令,我们将指向uwsgi可执行文件。 我们将告诉它运行在“Emperor模式”,允许它使用在/ etc / uwsgi / sites中找到的文件来管理多个应用程序。 我们还将添加Systemd所需的部分以正确管理进程。 这些是从uWSGI文档采取在这里

[Unit]
Description=uWSGI Emperor service

[Service]
ExecStartPre=/usr/bin/bash -c 'mkdir -p /run/uwsgi; chown user:nginx /run/uwsgi'
ExecStart=/usr/bin/uwsgi --emperor /etc/uwsgi/sites
Restart=always
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all

现在,我们需要做的是添加[Install]部分。 这允许我们指定何时应该自动启动服务。 我们将把我们的服务绑定到多用户系统状态。 每当系统设置为多个用户(正常操作条件)时,我们的服务将被激活:

[Unit]
Description=uWSGI Emperor service

[Service]
ExecStartPre=/usr/bin/bash -c 'mkdir -p /run/uwsgi; chown user:nginx /run/uwsgi'
ExecStart=/usr/bin/uwsgi --emperor /etc/uwsgi/sites
Restart=always
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all

[Install]
WantedBy=multi-user.target

完成此操作后,保存并关闭文件。

我们将无法在此时成功启动服务,因为它依赖于nginx用户可用。 我们将不得不等待启动uWSGI服务,直到Nginx安装后。

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

通过配置uWSGI并准备好,我们现在可以安装和配置Nginx作为我们的反向代理。 这可以通过下载yum通过键入:

sudo yum install nginx

一旦Nginx安装,我们可以继续修改服务器块配置。 我们将编辑主要的Nginx配置文件:

sudo nano /etc/nginx/nginx.conf

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

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

server {
    listen                  80 default_server;
    server_name             server_domain_or_IP;
    root                    /usr/share/nginx/html;

    include /etc/nginx/default.d/*.conf;

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

    . . .

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

server {
    listen                  80 default_server;
    server_name             server_domain_or_IP;
    root                    /usr/share/nginx/html;

    include /etc/nginx/default.d/*.conf;

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

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

    . . .

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

在文件的底部,但收盘内部http {}块支架,使另一个server {}块。 我们将使用它来配置SSL连接。

从基础开始。 此服务器块将侦听端口443(默认SSL端口)上的连接。 我们将设置服务器的域名或IP地址,就像我们对端口80服务器块一样。 要启动实际的SSL配置,我们将为此块指定应该启用SSL,我们将指明SSL证书的路径以及应用于加密连接的密钥。 我们会立即移动文件:

http {
    . . .
    server {
        listen 80;
        . . .
    }
    server {
        listen 443;
        server_name server_domain_or_IP;

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

我们将继续使用一些SSL模板来建立接受的协议和密码。 然后,我们可以设置在同一location / {}我们在80端口服务器配置挡块:

http {
    . . .
    server {
        listen 80;
        . . .
    }
    server {
        listen 443;
        server_name server_domain_or_IP;

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

        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:/run/uwsgi/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用户必须能够访问我们的应用程序目录,以便它可以直接支持静态文件是必要的。 CentOS的锁定了每个用户的主目录非常限制性,所以我们将添加nginx用户给我们的用户群,这样我们就可以打开需要得到这个功能的最低权限。

添加nginx键入该用户到组。 用您的用户名的user在下面的命令:

sudo usermod -a -G user nginx

现在,我们将给予我们的用户组对我们的目录的执行权限,这将允许Nginx进程输入和访问内容:

chmod 710 /home/user

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

sudo nginx -t

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

sudo service nginx start

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

sudo service uwsgi start

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

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

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

如果一切顺利,您可以通过键入以下命令启用Nginx和uWSGI在启动时启动:

sudo systemctl enable nginx
sudo systemctl enable uwsgi

结论

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

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