介绍
在本指南中,我们将使用CentOS 7上的Flask微框架设置一个简单的Python应用程序。本文的主要内容将是如何设置uWSGI应用程序服务器以启动应用程序,以及Nginx充当前端结束反向代理。
先决条件
在开始本指南之前,您应该在服务器上配置非root用户。 这个用户需要具有sudo
权限,以便可以执行管理功能。 要了解如何设置的,按照我们最初的服务器设置指南 。
要了解更多关于uWSGI,我们的应用服务器和WSGI规范,你可以阅读的链接部分本指南 。 了解这些概念将使本指南更容易遵循。
当您准备好继续时,请继续阅读。
从CentOS和EPEL存储库安装组件
我们的第一步是安装我们需要的所有零件,从存储库。 我们将需要添加EPEL存储库,其中包含一些额外的软件包,以便安装我们需要的一些组件。
您可以通过键入以下内容启用EPEL仓库:
sudo yum install epel-release
一旦在我们的系统上配置对EPEL存储库的访问,我们就可以开始安装我们需要的包。 我们将安装pip
,Python的包管理器,以便安装和管理我们的Python组件。 我们还将获得一个编译器和构建uWSGI所需的Python开发文件。 我们现在也将安装Nginx。
您可以通过键入以下内容安装所有这些组件:
sudo yum install python-pip python-devel gcc nginx
创建Python虚拟环境
接下来,我们将设置一个虚拟环境,以便将Flask应用程序与系统上的其他Python文件隔离开来。
通过安装启动virtualenv
使用包pip
:
sudo pip install virtualenv
现在,我们可以为我们的Flask项目创建一个父目录。 在创建目录后移动到目录:
mkdir ~/myproject
cd ~/myproject
我们可以创建一个虚拟环境来存储Flask项目的Python需求,方法是键入:
virtualenv myprojectenv
这将安装Python的本地副本和pip
变成一个名为myprojectenv
项目目录之内。
在我们在虚拟环境中安装应用程序之前,我们需要激活它。 您可以键入以下内容:
source myprojectenv/bin/activate
您的提示将更改为表示您现在在虚拟环境中操作。 它看起来像这样( myprojectenv ) user @ host :~/ myproject $
。
设置Flask应用程序
既然你在你的虚拟环境中,我们可以安装Flask和uWSGI,并开始设计我们的应用程序:
安装Flask和uWSGI
我们可以使用本地实例pip
安装瓶和uWSGI。 键入以下命令以获取这两个组件:
pip install uwsgi flask
创建示例应用程序
现在我们有Flask可用,我们可以创建一个简单的应用程序。 Flask是一个微框架。 它不包括许多更全功能的框架可能的工具,并且主要作为一个模块,您可以导入到您的项目,以帮助您初始化Web应用程序。
当你的应用程序可能会比较复杂,我们将创建我们在一个文件中,我们将其称为瓶应用myproject.py
:
nano ~/myproject/myproject.py
在这个文件中,我们将放置我们的应用程序代码。 基本上,我们需要导入Flask并实例化一个Flask对象。 我们可以使用它来定义当请求特定路由时应该运行的函数。 我们将调用代码瓶的应用application
来复制你的WSGI规范找到的例子:
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应用程序:
python myproject.py
访问您的服务器的域名或IP地址,然后在终端输出指定的端口号(最有可能的:5000
)在Web浏览器。 你应该看到这样的:
完成后,在终端窗口中按CTRL-C几次以停止Flask开发服务器。
创建WSGI入口点
接下来,我们将创建一个文件,作为我们的应用程序的入口点。 这将告诉我们的uWSGI服务器如何与应用程序交互。
我们将调用文件wsgi.py
:
nano ~/myproject/wsgi.py
该文件是非常简单的,我们可以简单地从我们的应用程序导入Flask实例,然后运行它:
from myproject import application
if __name__ == "__main__":
application.run()
保存并在完成后关闭文件。
配置uWSGI
我们的应用程序现在已经写好,我们的入口点已经建立。 我们现在可以进入uWSGI。
测试uWSGI服务
我们要做的第一件事是测试,以确保uWSGI可以服务于我们的应用程序。
我们可以通过简单地传递它的入口点的名称来做到这一点。 我们还需要指定插槽,以便它将一个公开的接口和协议,这样它会使用HTTP而不是上启动uwsgi
二进制协议:
uwsgi --socket 0.0.0.0:8000 --protocol=http -w wsgi
如果你访问你的服务器的域名或IP地址有:8000
追加到Web浏览器结束时,你应该会看到一个页面,如下所示:
当您确认它正常工作时,请在终端窗口中按CTRL-C。
我们现在已经完成了我们的虚拟环境,因此我们可以停用它:
deactivate
现在的任何操作都将对系统的Python环境完成。
创建uWSGI配置文件
我们测试了uWSGI能够为我们的应用程序服务,但我们需要更强大的长期使用。 我们可以使用我们想要的选项创建一个uWSGI配置文件。
让我们把在我们的项目目录,并调用它myproject.ini
:
nano ~/myproject/myproject.ini
在内部,我们将开始与[uwsgi]
让uWSGI知道应用设置标题。 我们将指定参照我们的模块wsgi.py
文件,减去扩展:
[uwsgi]
module = wsgi
接下来,我们将告诉uWSGI在主模式下启动,并生成五个工作进程来提供实际请求:
[uwsgi]
module = wsgi
master = true
processes = 5
当我们测试时,我们在网络端口上暴露uWSGI。 但是,我们将使用Nginx处理实际的客户端连接,然后将请求传递给uWSGI。 因为这些组件在同一台计算机上操作,所以优选Unix套接字,因为它更安全和更快。 我们将调用Socket myproject.sock
并将其放在此目录中。
我们还必须更改套接字上的权限。 我们稍后将给予uWSGI进程的Nginx组所有权,因此我们需要确保套接字的组所有者可以从其中读取信息并写入它。 我们还将通过添加“vacuum”选项在进程停止时清理套接字:
[uwsgi]
module = wsgi
master = true
processes = 5
socket = myproject.sock
chmod-socket = 660
vacuum = true
我们需要做的最后一件事是设置die-on-term
选择。 这是需要的,因为Upstart init系统和uWSGI有不同的想法,不同的过程信号应该是什么意思。 设置此操作将对齐两个系统组件,实现预期的行为:
[uwsgi]
module = wsgi
master = true
processes = 5
socket = myproject.sock
chmod-socket = 660
vacuum = true
die-on-term = true
您可能已经注意到,我们没有指定像从命令行那样的协议。 这是因为,在默认情况下,uWSGI讲得使用uwsgi
协议,一个快速二进制协议设计与其他服务器进行通信。 Nginx可以本地说这个协议,所以最好使用它,而不是通过HTTP强制通信。
完成后,保存并关闭文件。
创建Systemd单元文件
下一个我们需要关注的是Systemd服务单元文件。 创建Systemd单元文件将允许CentOS的init系统自动启动uWSGI,并在服务器启动时为我们的Flask应用程序提供服务。
创建结尾的单元文件.service
的范围内/etc/systemd/system
目录开始:
sudo nano /etc/systemd/system/myproject.service
里面,我们将在开始[Unit]
部分,它是用来指定的元数据和依赖关系。 我们将在这里描述我们的服务,并告诉init系统只有在达到网络目标后才启动:
[Unit]
Description=uWSGI instance to serve myproject
After=network.target
接下来,我们将打开[Service]
部分。 我们将指定我们希望进程运行的用户和组。 我们将给予流程的常规用户帐户所有权,因为它拥有所有相关文件。 我们将给予Nginx用户组所有权,以便它可以轻松地与uWSGI进程通信。
然后,我们将映射出工作目录,并设置PATH
环境变量,所以init系统知道我们该进程的可执行文件的位置(我们的虚拟environmment内)。 然后我们将指定启动服务的命令。 Systemd要求我们给出在我们的虚拟环境中安装的uWSGI可执行文件的完整路径。 我们将通过名称.ini
我们在项目目录下创建配置文件:
[Unit]
Description=uWSGI 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/uwsgi --ini myproject.ini
最后,我们将添加一个[Install]
部分。 这将告诉Systemd什么链接这个服务,如果我们启用它在启动时启动。 我们希望在常规多用户系统启动并运行时启动此服务:
[Unit]
Description=uWSGI 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/uwsgi --ini myproject.ini
[Install]
WantedBy=multi-user.target
这样,我们的Systemd服务文件就完成了。 保存并立即关闭。
我们现在可以启动我们创建的uWSGI服务,并启用它,以便它在启动时启动:
sudo systemctl start myproject
sudo systemctl enable myproject
配置Nginx到代理请求
我们的uWSGI应用程序服务器现在应该启动并运行,等待项目目录中的套接字文件上的请求。 我们需要配置Nginx的对Web请求传递到使用套接字uwsgi
协议。
首先打开Nginx的默认配置文件:
sudo nano /etc/nginx/nginx.conf
打开略高于其他的服务器块server {}
块已经在文件中:
http {
. . .
include /etc/nginx/conf.d/*.conf;
server {
}
server {
listen 80 default_server;
. . .
我们将把我们Flask应用程序的所有配置放在这个新块中。 我们将开始指定该块应该在默认端口80上侦听,并且它应该响应我们的服务器的域名或IP地址:
server {
listen 80;
server_name server_domain_or_IP;
}
我们需要添加的唯一的另一件事是一个匹配每个请求的位置块。 在此块中,我们将包括uwsgi_params
文件,指定需要被设置一些一般uWSGI参数。 然后,我们将通过请求,我们使用定义的插座uwsgi_pass
指令:
server {
listen 80;
server_name server_domain_or_IP;
location / {
include uwsgi_params;
uwsgi_pass unix:/home/user/myproject/myproject.sock;
}
}
这实际上是我们需要为我们的应用程序服务。 保存并在完成后关闭文件。
在nginx
用户必须以有访问套接字文件访问我们的应用程序目录。 默认情况下,CentOS的锁定了每个用户的主目录非常限制性,所以我们将添加nginx
用户给我们的用户群,这样我们就可以打通必要的授权访问的最低权限。
您可以添加nginx
用户用下面的命令到你的用户群。 替换自己的用户名的user
的命令:
sudo usermod -a -G user nginx
现在,我们可以给我们的用户组执行我们的主目录的权限。 这将允许Nginx进程输入和访问内容:
chmod 710 /home/user
使用权限设置,我们可以测试我们的Nginx配置文件的语法错误:
sudo nginx -t
如果这返回没有指示任何问题,我们可以启动和启用Nginx进程,以便它在启动时自动启动:
sudo systemctl start nginx
sudo systemctl enable nginx
您现在应该能够在Web浏览器中转到您服务器的域名或IP地址,并查看您的应用程序:
结论
在本指南中,我们在Python虚拟环境中创建了一个简单的Flask应用程序。 我们创建一个WSGI入口点,以便任何支持WSGI的应用程序服务器可以与它接口,然后配置uWSGI应用程序服务器以提供此功能。 之后,我们创建了Systemd服务单元文件,以在引导时自动启动应用程序服务器。 我们创建了一个Nginx服务器块,将Web客户端流量传递到应用程序服务器,中继外部请求。
Flask是一个非常简单但非常灵活的框架,旨在为您的应用程序提供功能,而不会对结构和设计造成过多的限制。 您可以使用本指南中描述的常规来为您设计的Flask应用程序提供服务。