在本指南中,我们将在 Ubuntu 14.04 上使用 Flask 微框架设置一个简单的 Python 应用程序。本文的大部分内容将介绍如何设置 uWSGI 应用程序服务器来启动应用程序以及如何设置 Nginx 作为前端反向代理。
在开始本指南之前,您应该在服务器上配置一个非 root 用户。该用户需要有sudo
权限,以便它可以执行管理功能。要了解如何进行设置,请按照我们的初始服务器设置指南.
要了解有关 uWSGI、我们的应用程序服务器和 WSGI 规范的更多信息,您可以阅读以下链接的部分本指南。了解这些概念将使本指南更容易理解。
当您准备好继续时,请继续阅读。
我们的第一步是从存储库安装我们需要的所有部分。我们将安装pip
,Python 包管理器,用于安装和管理我们的 Python 组件。我们还将获得构建 uWSGI 所需的 Python 开发文件,并且现在我们还将安装 Nginx。
更新本地包索引,然后通过键入以下内容安装包:
sudo apt-get update
sudo apt-get install python-pip python-dev nginx
接下来,我们将设置一个虚拟环境,以便将 Flask 应用程序与系统上的其他 Python 文件隔离。
首先安装virtualenv
封装使用pip
:
sudo pip install virtualenv
现在,我们可以为 Flask 项目创建一个父目录。创建目录后移至该目录:
mkdir ~/myproject
cd ~/myproject
我们可以通过输入以下命令来创建一个虚拟环境来存储 Flask 项目的 Python 需求:
virtualenv myprojectenv
This will install a local copy of Python and pip
into a directory called myprojectenv
within your project directory.
在虚拟环境中安装应用程序之前,我们需要激活它。您可以通过输入以下内容来执行此操作:
source myprojectenv/bin/activate
Your prompt will change to indicate that you are now operating within the virtual environment. It will look something like this (myprojectenv)user@host:~/myproject$
.
现在您已处于虚拟环境中,我们可以安装 Flask 和 uWSGI 并开始设计我们的应用程序:
我们可以使用本地实例pip
安装 Flask 和 uWSGI。键入以下命令来获取这两个组件:
pip install uwsgi flask
现在我们有了 Flask,我们可以创建一个简单的应用程序。 Flask 是一个微框架。它不包含功能更齐全的框架可能提供的许多工具,主要作为一个模块存在,您可以将其导入到项目中以帮助您初始化 Web 应用程序。
虽然您的应用程序可能更复杂,但我们将在单个文件中创建 Flask 应用程序,我们将其称为myproject.py
:
nano ~/myproject/myproject.py
在此文件中,我们将放置我们的应用程序代码。基本上,我们需要导入 Flask 并实例化 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
)在您的网络浏览器中。你应该看到这样的东西:
完成后,在终端窗口中按 CTRL-C 几次以停止 Flask 开发服务器。
接下来,我们将创建一个文件作为应用程序的入口点。这将告诉我们的 uWSGI 服务器如何与应用程序交互。
我们将调用该文件wsgi.py
:
nano ~/myproject/wsgi.py
该文件非常简单,我们可以简单地从应用程序导入 Flask 实例,然后运行它:
from myproject import application
if __name__ == "__main__":
application.run()
完成后保存并关闭文件。
现在我们的应用程序已经编写完毕,并且我们的入口点也已建立。我们现在可以转向 uWSGI。
我们要做的第一件事是测试以确保 uWSGI 可以为我们的应用程序提供服务。
我们只需将入口点的名称传递给它即可做到这一点。我们还将指定套接字,以便它将在公共可用的接口和协议上启动,以便它将使用 HTTP 而不是uwsgi
二进制协议:
uwsgi --socket 0.0.0.0:8000 --protocol=http -w wsgi
如果您访问服务器的域名或IP地址:8000
附加到网络浏览器的末尾,您应该看到如下所示的页面:
当您确认其正常运行后,请在终端窗口中按 CTRL-C。
现在我们已经完成了虚拟环境,因此我们可以停用它:
deactivate
现在的任何操作都将在系统的Python环境中完成。
我们已经测试过 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 套接字,因为它更安全、更快。我们将调用套接字myproject.sock
并将其放置在该目录中。
我们还必须更改套接字上的权限。稍后我们将向 Nginx 组授予 uWSGI 进程的所有权,因此我们需要确保套接字的组所有者可以从中读取信息并向其写入信息。当进程停止时,我们还将通过添加“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 进行通信更好。
完成后,保存并关闭文件。
我们需要处理的下一个部分是 Upstart 脚本。创建一个 Upstart 脚本将允许 Ubuntu 的 init 系统在服务器启动时自动启动 uWSGI 并为我们的 Flask 应用程序提供服务。
创建一个以以下结尾的脚本文件.conf
内/etc/init
开始目录:
sudo nano /etc/init/myproject.conf
在里面,我们将从脚本用途的简单描述开始。之后,我们将立即定义系统启动和停止该脚本的条件。正常的系统运行时编号为 2、3、4 和 5,因此我们将告诉它在系统达到这些运行级别之一时启动我们的脚本。我们将告诉它在任何其他运行级别停止(例如当服务器重新启动、关闭或处于单用户模式时):
description "uWSGI server instance configured to serve myproject"
start on runlevel [2345]
stop on runlevel [!2345]
接下来,我们需要定义 uWSGI 运行的用户和组。我们的项目文件都是由我们自己的用户帐户拥有的,所以我们将自己设置为用户来运行。 Nginx 服务器运行在www-data
团体。我们需要 Nginx 能够读取和写入套接字文件,因此我们将授予该组对该进程的所有权:
description "uWSGI server instance configured to serve myproject"
start on runlevel [2345]
stop on runlevel [!2345]
setuid user
setgid www-data
接下来,我们需要设置进程,以便它可以正确找到我们的文件并处理它们。我们已经将所有 Python 组件安装到虚拟环境中,因此我们需要设置一个环境变量并将其作为路径。我们还需要更改到我们的项目目录。之后,我们可以简单地调用uWSGI可执行文件并将我们编写的配置文件传递给它:
description "uWSGI server instance configured to serve myproject"
start on runlevel [2345]
stop on runlevel [!2345]
setuid user
setgid www-data
env PATH=/home/user/myproject/myprojectenv/bin
chdir /home/user/myproject
exec uwsgi --ini myproject.ini
完成后保存并关闭文件。
您可以通过键入以下内容立即开始该过程:
sudo start myproject
我们的uWSGI应用程序服务器现在应该启动并运行,等待项目目录中套接字文件的请求。我们需要配置 Nginx 以使用以下命令将 Web 请求传递到该套接字uwsgi
协议。
首先在 Nginx 中创建一个新的服务器块配置文件sites-available
目录。我们简单地称之为myproject
为了与指南的其余部分保持一致:
sudo nano /etc/nginx/sites-available/myproject
打开一个服务器块并告诉 Nginx 监听默认端口 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 服务器块配置,请将文件链接到sites-enabled
目录:
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
使用该目录中的文件,我们可以通过键入以下内容来测试语法错误:
sudo nginx -t
如果返回时没有表明任何问题,我们可以重新启动 Nginx 进程来读取新配置:
sudo service nginx restart
您现在应该能够在 Web 浏览器中访问服务器的域名或 IP 地址并查看您的应用程序:
在本指南中,我们在 Python 虚拟环境中创建了一个简单的 Flask 应用程序。我们创建一个 WSGI 入口点,以便任何支持 WSGI 的应用程序服务器都可以与其交互,然后配置 uWSGI 应用程序服务器来提供此功能。之后,我们创建了一个 Upstart 脚本来在启动时自动启动应用程序服务器。我们创建了一个 Nginx 服务器块,它将 Web 客户端流量传递到应用程序服务器,中继外部请求。
Flask 是一个非常简单但极其灵活的框架,旨在为您的应用程序提供功能,而不会在结构和设计方面受到太多限制。您可以使用本指南中描述的通用堆栈来服务您设计的 Flask 应用程序。