如何在 Ubuntu 16.04 上使用 uWSGI 和 Nginx 提供 Flask 应用程序
在本指南中,我们将在 Ubuntu 16.04 上使用 Flask 微框架设置一个简单的 Python 应用程序。本文的大部分内容将介绍如何设置 uWSGI 应用服务器来启动应用程序,并使用 Nginx 作为前端反向代理。
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。
简介
在本指南中,我们将在 Ubuntu 16.04 上使用 Flask 微框架设置一个简单的 Python 应用程序。本文的大部分内容将介绍如何设置 uWSGI 应用服务器来启动应用程序,并使用 Nginx 作为前端反向代理。
先决条件
在开始本指南之前,您应该在服务器上配置一个非根用户。该用户需要具有 sudo
权限,以便可以执行管理功能。要了解如何设置,请参阅我们的初始服务器设置指南。
要了解更多关于 uWSGI、我们的应用服务器和 WSGI 规范的信息,您可以阅读本指南的相关部分。了解这些概念将使本指南更容易理解。
当您准备好继续时,请继续阅读。
从 Ubuntu 仓库安装组件
我们的第一步将是从仓库中安装我们需要的所有组件。我们将安装 pip
,即 Python 包管理器,以便安装和管理我们的 Python 组件。我们还将获取构建 uWSGI 所需的 Python 开发文件,并立即安装 Nginx。
我们需要更新本地软件包索引,然后安装这些软件包。您需要的软件包取决于您的项目是使用 Python 2 还是 Python 3。
如果您使用 Python 2,请输入:
sudo apt-get update
sudo apt-get install python-pip python-dev nginx
如果您使用 Python 3,请输入:
sudo apt-get update
sudo apt-get install python3-pip python3-dev nginx
创建 Python 虚拟环境
接下来,我们将设置一个虚拟环境,以便将我们的 Flask 应用程序与系统上的其他 Python 文件隔离开来。
首先,使用 pip
安装 virtualenv
包。
如果您使用 Python 2,请输入:
sudo pip install virtualenv
如果您使用 Python 3,请输入:
sudo pip3 install virtualenv
现在,我们可以在我们的 Flask 项目的父目录中创建一个虚拟环境。创建后,进入该目录:
mkdir ~/myproject
cd ~/myproject
我们可以通过输入以下命令来创建一个虚拟环境,以存储我们的 Flask 项目的 Python 需求:
virtualenv myprojectenv
这将在您的项目目录中的名为 myprojectenv
的目录中安装 Python 和 pip
的本地副本。
在虚拟环境中安装应用程序之前,我们需要激活它。您可以通过输入以下命令来激活它:
source myprojectenv/bin/activate
您的提示符将更改以指示您现在正在虚拟环境中操作。它看起来类似于 (myprojectenv)user@host:~/myproject$
。
设置 Flask 应用程序
现在您已经在虚拟环境中,我们可以安装 Flask 和 uWSGI,并开始设计我们的应用程序:
安装 Flask 和 uWSGI
我们可以使用本地的 pip
实例来安装 Flask 和 uWSGI。输入以下命令来获取这两个组件:
pip install uwsgi flask
创建一个示例应用
现在我们有了 Flask,我们可以创建一个简单的应用程序。Flask 是一个微框架。它不包括许多更全面的框架可能包含的工具,主要作为一个模块存在,您可以将其导入到您的项目中,以帮助您初始化 Web 应用程序。
虽然您的应用程序可能更复杂,我们将在一个名为 myproject.py
的单个文件中创建我们的 Flask 应用程序:
nano ~/myproject/myproject.py
在这个文件中,我们将放置我们的应用程序代码。基本上,我们需要导入 Flask 并实例化一个 Flask 对象。我们可以使用它来定义在请求特定路由时应运行的函数:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "<h1 style='color:blue'>Hello There!</h1>"
if __name__ == "__main__":
app.run(host='0.0.0.0')
这基本上定义了在访问根域时要呈现的内容。完成后保存并关闭文件。
如果您遵循了初始服务器设置指南,您应该已经启用了 UFW 防火墙。为了测试我们的应用程序,我们需要允许访问端口 5000。
通过输入以下命令打开端口 5000:
sudo ufw allow 5000
现在,您可以通过输入以下命令来测试您的 Flask 应用程序:
python myproject.py
在 Web 浏览器中访问您的服务器域名或 IP 地址,后面加上 :5000
:
http://server_domain_or_IP:5000
您应该会看到类似于以下内容:
!Flask sample app
完成后,在终端窗口中多次按下 CTRL-C 以停止 Flask 开发服务器。
创建 WSGI 入口点
接下来,我们将创建一个文件,作为应用程序的入口点。这将告诉我们的 uWSGI 服务器如何与应用程序交互。
我们将把文件命名为 wsgi.py
:
nano ~/myproject/wsgi.py
这个文件非常简单,我们只需从我们的应用程序中导入 Flask 实例,然后运行它:
from myproject import app
if __name__ == "__main__":
app.run()
完成后保存并关闭文件。
配置 uWSGI
我们的应用程序现在已经编写好,入口点也已经建立。现在我们可以继续配置 uWSGI。
测试 uWSGI 服务
我们首先要做的是测试 uWSGI 是否能够提供我们的应用程序。
我们可以通过简单地传递入口点的名称来测试。这是由模块的名称(通常情况下去掉 .py
扩展名)加上应用程序中的可调用名称构成的。在我们的情况下,这将是 wsgi:app
。
我们还将指定套接字,以便它将在公共可用接口上启动,并指定协议,以便它将使用 HTTP 而不是 uwsgi
二进制协议。我们将使用之前打开的相同端口号:
uwsgi --socket 0.0.0.0:5000 --protocol=http -w wsgi:app
再次在浏览器中访问您服务器的域名或 IP 地址,并在末尾添加 :5000
:
http://server_domain_or_IP:5000
您应该再次看到应用程序的输出:
!Flask sample app
确认它正常运行后,在终端窗口中按下 CTRL-C。
现在我们已经完成了虚拟环境,所以我们可以将其停用:
deactivate
任何 Python 命令现在将再次使用系统的 Python 环境。
创建 uWSGI 配置文件
我们已经测试过 uWSGI 能够提供我们的应用程序,但是我们希望为长期使用创建一个更健壮的 uWSGI 配置文件。我们可以创建一个带有我们想要的选项的 uWSGI 配置文件。
让我们将其放在我们的项目目录中,并将其命名为 myproject.ini
:
nano ~/myproject/myproject.ini
在文件中,我们将首先使用 [uwsgi]
标头,以便 uWSGI 知道应用这些设置。我们将通过引用我们的 wsgi.py
文件(去掉扩展名)来指定模块,并且文件中的可调用名称为 “app”:
[uwsgi]
module = wsgi:app
接下来,我们将告诉 uWSGI 以主模式启动,并生成五个工作进程来处理实际请求:
[uwsgi]
module = wsgi:app
master = true
processes = 5
在测试时,我们在网络端口上暴露了 uWSGI。然而,我们将使用 Nginx 来处理实际的客户端连接,然后将请求传递给 uWSGI。由于这些组件在同一台计算机上运行,因此更倾向于使用 Unix 套接字,因为它更安全且更快。我们将称套接字为 myproject.sock
,并将其放在此目录中。
我们还需要更改套接字的权限。稍后我们将把 Nginx 组的所有权赋予 uWSGI 进程,因此我们需要确保套接字的组所有者可以从中读取信息并向其写入。当进程停止时,我们还需要清理套接字,通过添加 “vacuum” 选项来实现:
[uwsgi]
module = wsgi:app
master = true
processes = 5
socket = myproject.sock
chmod-socket = 660
vacuum = true
最后一件事是设置 die-on-term
选项。这有助于确保初始化系统和 uWSGI 对每个进程信号的含义有相同的假设。设置这一点可以使这两个系统组件保持一致,实现预期的行为:
[uwsgi]
module = wsgi:app
master = true
processes = 5
socket = myproject.sock
chmod-socket = 660
vacuum = true
die-on-term = true
您可能已经注意到,我们没有像在命令行中那样指定协议。这是因为默认情况下,uWSGI 使用 uwsgi
协议,这是一种快速的二进制协议,旨在与其他服务器通信。Nginx 可以原生地使用这种协议,因此最好使用这种协议,而不是强制使用 HTTP 进行通信。
完成后保存并关闭文件。
创建一个 systemd 单元文件
接下来,我们需要处理的是 systemd 服务单元文件。创建一个 systemd 单元文件将允许 Ubuntu 的 init 系统在服务器启动时自动启动 uWSGI 并提供我们的 Flask 应用程序。
首先,在 /etc/systemd/system 目录中创建一个以 .service 结尾的单元文件:
sudo nano /etc/systemd/system/myproject.service
在文件中,我们将从 [Unit]
部分开始,该部分用于指定元数据和依赖关系。我们将在这里放置我们服务的描述,并告诉 init 系统仅在网络目标达到后才启动此服务:
[Unit]
Description=uWSGI instance to serve myproject
After=network.target
接下来,我们将打开 [Service]
部分。我们将指定要运行进程的用户和组。我们将使用我们的常规用户帐户拥有该进程,因为它拥有所有相关文件。我们将给 www-data
组拥有权,以便 Nginx 可以轻松地与 uWSGI 进程通信。
然后,我们将映射工作目录并设置 PATH
环境变量,以便 init 系统知道进程的可执行文件位于何处(在我们的虚拟环境中)。然后,我们将指定启动服务的命令。Systemd 要求我们提供到 uWSGI 可执行文件的完整路径,该文件安装在我们的虚拟环境中。我们将传递我们在项目目录中创建的 .ini 配置文件的名称:
[Unit]
Description=uWSGI instance to serve myproject
After=network.target
[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myproject
Environment="PATH=/home/sammy/myproject/myprojectenv/bin"
ExecStart=/home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.ini
最后,我们将添加一个 [Install]
部分。这将告诉 systemd 如果我们启用它以在启动时启动,要将此服务链接到什么。我们希望此服务在常规的多用户系统启动并运行时启动:
[Unit]
Description=uWSGI instance to serve myproject
After=network.target
[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myproject
Environment="PATH=/home/sammy/myproject/myprojectenv/bin"
ExecStart=/home/sammy/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 以使用 uwsgi
协议将 web 请求传递到该套接字。
首先,在 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/sammy/myproject/myproject.sock;
}
}
这实际上就是我们需要为我们的应用程序提供服务的所有内容。完成后保存并关闭文件。
要启用我们刚刚创建的 Nginx 服务器块配置,将文件链接到 sites-enabled
目录:
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
将文件放在该目录中后,我们可以通过输入以下命令来测试语法错误:
sudo nginx -t
如果没有指示任何问题,我们可以重新启动 Nginx 进程以读取我们的新配置:
sudo systemctl restart nginx
我们需要做的最后一件事是再次调整我们的防火墙。我们不再需要通过端口 5000 进行访问,因此我们可以删除该规则。然后,我们可以允许访问 Nginx 服务器:
sudo ufw delete allow 5000
sudo ufw allow 'Nginx Full'
现在,您应该能够在 web 浏览器中输入服务器的域名或 IP 地址:
http://server_domain_or_IP
您应该能够看到您的应用程序输出:
!Flask sample app
结论
在本指南中,我们在 Python 虚拟环境中创建了一个简单的 Flask 应用程序。我们创建了一个 WSGI 入口点,以便任何支持 WSGI 的应用程序服务器都可以与其进行交互,然后配置了 uWSGI 应用服务器以提供此功能。随后,我们创建了一个 systemd 服务文件,以便在启动时自动启动应用程序服务器。我们创建了一个 Nginx 服务器块,将 Web 客户端流量传递到应用程序服务器,中继外部请求。
Flask 是一个非常简单但极其灵活的框架,旨在为您的应用程序提供功能,而不会对结构和设计施加太多限制。您可以使用本指南中描述的通用堆栈来为您设计的 Flask 应用程序提供服务。

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。
更多推荐
所有评论(0)