如何在CentOS 7上使用Gunicorn和Nginx为Flask应用程序提供服务

2018-10-22 11:38:37 浏览数 (1)

介绍

在本指南中,我们将使用CentOS 7上的Flask微框架设置一个简单的Python应用程序。本文的大部分内容将是关于如何设置Gunicorn应用程序服务器以启动应用程序和Nginx作为前端结束反向代理。

准备

一台已经设置好可以使用sudo命令的非root账号的CentOS服务器,并且已开启防火墙。没有服务器的同学可以在这里购买,不过我个人更推荐您使用免费的腾讯云开发者实验室进行试验,学会安装后再购买服务器。

当您准备好继续时,请继续阅读。

从CentOS和EPEL存储库安装组件

我们的第一步是从存储库安装我们需要的所有部分。我们需要添加EPEL存储库,其中包含一些额外的包,以便安装我们需要的一些组件。

您可以键入以下命令启用EPEL回购:

代码语言:javascript复制
sudo yum install epel-release

一旦在我们的系统上配置了对EPEL存储库的访问,我们就可以开始安装我们需要的软件包。我们将安装Python包管理器pip,以便安装和管理我们的Python组件。我们还将获得Gunicorn所需的编译器和Python开发文件。我们现在也会安装Nginx。

您可以键入以下命令安装所有这些组件:

代码语言:javascript复制
sudo yum install python-pip python-devel gcc nginx

创建Python虚拟环境

接下来,我们将设置一个虚拟环境,以便将Flask应用程序与系统上的其他Python文件隔离开来。

首先使用pip方法安装virtualenv软件包:

代码语言:javascript复制
sudo pip install virtualenv

现在,我们可以为Flask项目创建一个上级目录。创建后移动到目录:

代码语言:javascript复制
mkdir ~/myproject
cd ~/myproject

我们可以通过输入以下内容创建一个虚拟环境来存储我们的Flask项目的Python需求:

代码语言:javascript复制
virtualenv myprojectenv

这将安装Python的本地副本和pip进入项目目录中的myprojectenv目录。

在我们在虚拟环境中安装应用程序之前,我们需要激活它。您可以输入以下命令:

代码语言:javascript复制
source myprojectenv/bin/activate

您的提示将更改为表示您现在正在虚拟环境中运行。它看起来像这样:(myprojectenv)user@host:~/myproject$

设置Flask应用程序

现在您已进入虚拟环境,我们可以安装Flask和Gunicorn并开始设计我们的应用程序:

安装Flask和Gunicorn

我们可以使用本地实例pip来安装Flask和Gunicorn。键入以下命令以获取这两个组件:

代码语言:javascript复制
pip install gunicorn flask

创建示例应用程序

现在我们已经有了Flask,我们可以创建一个简单的应用程序。Flask是一个微框架。它不包括许多功能更全面的框架可能存在的工具,并且主要作为一个模块存在,您可以将其导入到项目中以帮助您初始化Web应用程序。

虽然您的应用程序可能更复杂,但我们将在单个文件中创建Flask应用程序,我们将调用它myproject.py

代码语言:javascript复制
nano ~/myproject/myproject.py

在此文件中,我们将放置我们的应用程序代码。基本上,我们需要导入flask并实例化Flask对象。我们可以使用它来定义在请求特定路由时应该运行的函数。我们将在代码中调用Flask应用程序application来复制您在WSGI规范中找到的示例:

代码语言:javascript复制
from flask import Flask
application = Flask(__name__)
​
@application.route("/")
def hello():
    return "<h1 style='color:blue'>Hello There!</h1>"
​
if __name__ == "__main__":
    application.run(host='0.0.0.0')

这基本上定义了访问根域时要呈现的内容。完成后保存并关闭文件。

您可以输入以下命令测试Flask应用:

代码语言:javascript复制
python myproject.py

访问服务器的域名或IP地址,然后访问:5000Web浏览器中终端输出(最有可能)中指定的端口号。你应该看到这样的东西:

完成后,在终端窗口中按CTRL-C几次以停止Flask开发服务器。

创建WSGI入口点

接下来,我们将创建一个文件,作为我们应用程序的入口点。这将告诉我们的Gunicorn服务器如何与应用程序进行交互。

我们将命名该文件wsgi.py

代码语言:javascript复制
nano ~/myproject/wsgi.py

该文件非常简单,我们只需从我们的应用程序导入Flask实例,然后运行它:

代码语言:javascript复制
from myproject import application
​
if __name__ == "__main__":
    application.run()

完成后保存并关闭文件。

测试Gunicorn服务项目的能力

在继续之前,我们应该检查Gunicorn能否正确。

我们可以通过简单地传递入口点的名称来实现这一点。我们还将指定要绑定的接口和端口,以便它可以在公共可用的接口上启动:

代码语言:javascript复制
cd ~/myproject
gunicorn --bind 0.0.0.0:8000 wsgi

如果您访问服务器的域名或IP地址:8000并附加到Web浏览器的末尾,您应该会看到如下所示的页面:

确认它运行正常后,在终端窗口中按CTRL-C。

我们现在已经完成了虚拟环境,因此我们可以将其停用:

代码语言:javascript复制
deactivate

现在任何操作都将在系统的Python环境中完成。

创建一个系统单元文件

我们需要处理的下一件事是Systemd服务单元文件。创建Systemd单元文件将允许CentOS的init系统自动启动Gunicorn,并在服务器启动时为Flask应用程序提供服务。

创建一个/etc/systemd/system目录以.service结尾的文件来开始:

代码语言:javascript复制
sudo nano /etc/systemd/system/myproject.service

在里面,我们将从一个[Unit]部分开始,该部分用于指定元数据和依赖关系。我们将在此处描述我们的服务并告诉init系统仅在达到网络目标后启动它:

代码语言:javascript复制
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target

接下来,我们将打开该[Service]部分。我们将指定我们希望在其下运行进程的用户和组。我们将为该流程提供常规用户帐户所有权,因为它拥有所有相关文件。我们将授予Nginx用户组所有权,以便它可以与Gunicorn流程轻松通信。

然后,我们将映射工作目录并设置PATH环境变量,以便init系统知道进程的可执行文件所在的位置(在我们的虚拟环境中)。然后我们将指定命令启动服务。Systemd要求我们提供Gunicorn可执行文件的完整路径,该文件安装在我们的虚拟环境中。

我们将告诉它启动3个工作进程(必要时调整它)。我们还将告诉它在我们的项目目录中创建并绑定到一个Unix套接字文件myproject.sock。我们将设置一个umask值007,以便创建套接字文件,从而允许访问所有者和组,同时限制其他访问。最后,我们需要传入WSGI入口点文件名:

代码语言:javascript复制
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target
​
[Service]
User=user
Group=nginx
WorkingDirectory=/home/user/myproject
Environment="PATH=/home/user/myproject/myprojectenv/bin"
ExecStart=/home/user/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi

我们需要添加到文件的最后一部分是一个[Install]部分。如果我们在启动时启动它,这将告诉Systemd将此服务链接到何处。我们希望在常规多用户系统启动并运行时启动此服务:

代码语言:javascript复制
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target
​
[Service]
User=user
Group=nginx
WorkingDirectory=/home/user/myproject
Environment="PATH=/home/user/myproject/myprojectenv/bin"
ExecStart=/home/user/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi
​
[Install]
WantedBy=multi-user.target

这样,我们的Systemd服务文件就完成了。立即保存并关闭它。

我们现在可以启动我们创建的Gunicorn服务并启用它以便它在启动时启动:

代码语言:javascript复制
sudo systemctl start myproject
sudo systemctl enable myproject

配置Nginx到代理请求

我们的Gunicorn应用程序服务器现在应该启动并运行,等待项目目录中的套接字文件上的请求。我们需要配置Nginx,通过对其配置文件进行一些小的添加,将Web请求传递给该套接字。

首先打开Nginx的默认配置文件:

代码语言:javascript复制
sudo nano /etc/nginx/nginx.conf

在文件中已存在的另一个块上方打开一个服务器块server {}

代码语言:javascript复制
http {
    . . .
​
    include /etc/nginx/conf.d/*.conf;
​
    server {
    }
​
    server {
        listen 80 default_server;
​
        . . .

我们将把Flask应用程序的所有配置放在这个新块中。我们将首先指定此块应该侦听默认端口80,并且它应该响应我们服务器的域名或IP地址:

代码语言:javascript复制
server {
    listen 80;
    server_name server_domain_or_IP;
}

我们需要添加的唯一其他内容是匹配每个请求的位置块。在这个块中,我们将设置一些标准的代理HTTP头,以便Gunicorn可以获得有关远程客户端连接的一些信息。然后,我们将流量传递给我们在Systemd单元文件中指定的套接字:

代码语言:javascript复制
server {
    listen 80;
    server_name server_domain_or_IP;
​
    location / {
        proxy_set_header Host $http_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-Proto $scheme;
        proxy_pass http://unix:/home/user/myproject/myproject.sock;
    }
}

完成后保存并关闭文件。

nginx用户必须具有以便在那里访问套接字文件访问我们的应用程序目录。默认情况下,CentOS会严格限制每个用户的主目录,因此我们会将nginx用户添加到用户的组中,以便我们可以打开授予访问权限所需的最低权限。

您可以使用以下命令将nginx用户添加到用户组。用命令中的自己的用户名替换user

代码语言:javascript复制
sudo usermod -a -G user nginx

现在,我们可以在我们的主目录上为我们的用户组授予执行权限。这将允许Nginx进程输入和访问以下内容:

代码语言:javascript复制
chmod 710 /home/user

设置权限后,我们可以测试我们的Nginx配置文件是否存在语法错误:

代码语言:javascript复制
sudo nginx -t

如果返回没有指出任何问题,我们可以启动并启用Nginx进程,以便它在启动时自动启动:

代码语言:javascript复制
sudo systemctl start nginx
sudo systemctl enable nginx

您现在应该可以在Web浏览器中访问服务器的域名或IP地址,并查看您的应用程序:

结论

在本指南中,我们在Python虚拟环境中创建了一个简单的Flask应用程序。我们创建一个WSGI入口点,以便任何支持WSGI的应用程序服务器都可以与它连接,然后配置Gunicorn应用程序服务器以提供此功能。之后,我们创建了一个Systemd单元文件,以便在引导时自动启动应用程序服务器。我们创建了一个Nginx服务器块,它将Web客户端流量传递给应用服务器,从而转发外部请求。

Flask是一个非常简单但非常灵活的框架,旨在为您的应用程序提供功能,而不会对结构和设计过于严格限制。您可以使用本指南中描述的常规堆栈来为您设计的烧瓶应用程序提供服务。

更多CentOS教程请前往腾讯云 社区学习更多知识。


参考文献:《How To Serve Flask Applications with Gunicorn and Nginx on CentOS 7》

0 人点赞