前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。
简介
在本指南中,您将在 Ubuntu 18.04 上使用 Flask 微框架构建一个 Python 应用程序。本文的大部分内容将介绍如何设置 Gunicorn 应用服务器,以及如何启动应用程序并配置 Nginx 作为前端反向代理。
先决条件
要完成本教程,您需要:
-
安装了 Ubuntu 18.04 的服务器,一个具有 sudo 权限的非 root 用户,并启用了防火墙。请参考我们的初始服务器设置指南。
-
已安装 Nginx,按照《在 Ubuntu 18.04 上安装 Nginx 的步骤 1 和 2》进行操作。
-
配置了指向您服务器的域名。您可以在 Namecheap 上购买域名,也可以在 Freenom 上免费获取域名。您可以按照有关域名和 DNS 的相关文档来了解如何将域名指向 DigitalOcean。确保创建以下 DNS 记录:
- 将
your_domain
指向您服务器的公共 IP 地址的 A 记录。 - 将
www.your_domain
指向您服务器的公共 IP 地址的 A 记录。
- 将
-
熟悉 WSGI 规范,Gunicorn 服务器将使用该规范与您的 Flask 应用程序进行通信。本讨论将更详细地介绍 WSGI。
步骤 1 — 从 Ubuntu 仓库安装组件
第一步是从默认的 Ubuntu 仓库安装所有必要的软件包。这包括 pip
,Python 包管理器,它将管理您的 Python 组件。您还将获得构建一些 Gunicorn 组件所需的 Python 开发文件。
首先,更新本地软件包:
sudo apt update
然后安装以下软件包,这些软件包将允许您构建 Python 环境。这些包括 python3-pip
,以及一些更多的软件包和开发工具,这些对于一个强大的编程环境是必要的:
sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools
安装了这些软件包后,继续创建您项目的虚拟环境。
步骤 2 — 创建 Python 虚拟环境
接下来,设置一个虚拟环境,以将您的 Flask 应用程序与系统上的其他 Python 文件隔离开来。
首先安装 python3-venv
软件包,它将安装 venv
模块:
sudo apt install python3-venv
然后,为您的 Flask 项目创建一个父目录:
mkdir ~/myproject
在创建后进入该目录:
cd ~/myproject
通过输入以下命令创建一个虚拟环境,以存储您的 Flask 项目的 Python 要求:
python3.6 -m venv myprojectenv
这将在您的项目目录中的一个名为 myprojectenv
的目录中安装 Python 和 pip
的本地副本。
在虚拟环境中安装应用程序之前,您需要通过运行以下命令来激活它:
source myprojectenv/bin/activate
您的提示符将更改以指示您现在正在虚拟环境中操作。它将显示如下内容:
(myprojectenv)\ssammy@host:~/myproject$
步骤 3 — 设置 Flask 应用程序
现在您已经在虚拟环境中,可以安装 Flask 和 Gunicorn,并开始设计您的应用程序。
首先,使用本地实例的 pip
安装 wheel
,以确保即使缺少 wheel 存档,您的软件包也能安装成功:
pip install wheel
接下来,安装 Flask 和 Gunicorn:
pip install gunicorn flask
现在您已经可以在下一步中创建一个基本应用程序。
创建一个示例应用程序
由于 Flask 是一个微框架,它不包含许多更全面的框架可能包含的工具。Flask 主要作为一个模块存在,您可以将其导入到您的项目中,以帮助初始化 Web 应用程序。
虽然您的应用程序可能更复杂,但我们将在一个名为 myproject.py
的单个文件中创建我们的 Flask 应用程序。使用您喜欢的文本编辑器创建此文件;这里我们将使用 nano
:
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')
这定义了在访问根域时要呈现的内容。完成后保存并关闭文件。如果您使用的是 nano,可以按 CTRL + X
然后 Y
和 ENTER
来完成此操作。
如果您按照先决条件中的初始服务器设置指南进行了操作,应该已经启用了 UFW 防火墙。要测试应用程序,首先需要允许访问端口 5000
:
sudo ufw allow 5000
然后,您可以通过运行以下命令来测试您的 Flask 应用程序:
python myproject.py
您将收到以下输出,其中包括一个有用的警告,提醒您不要在生产环境中使用此服务器设置:
* Serving Flask app 'myproject' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on all addresses.
WARNING: This is a development server. Do not use it in a production deployment.
* Running on http://your_server_ip:5000/ (Press CTRL+C to quit)
在 Web 浏览器中访问您服务器的 IP 地址,后面加上 :5000
:
http://your_server_ip:5000
您应该会收到类似以下内容:
!Flask sample app
完成后,按 CTRL + C
来停止 Flask 开发服务器。
创建 WSGI 入口点
接下来,创建一个文件作为应用程序的入口点。这将告诉 Gunicorn 服务器如何与应用程序进行交互。
使用您喜欢的文本编辑器创建一个新文件并命名。在这里,我们将文件命名为 wsgi.py
:
nano ~/myproject/wsgi.py
在这个文件中,从应用程序中导入 Flask 实例,然后运行它:
from myproject import app
if __name__ == "__main__":
app.run()
完成后保存并关闭文件。
步骤 4 —— 配置 Gunicorn
您的应用程序现在已经编写了一个已建立的入口点,您可以继续配置 Gunicorn。
首先,切换到适当的目录:
cd ~/myproject
接下来,您可以通过传递入口点的名称来检查 Gunicorn 是否可以正确地提供应用程序。这是构建为模块的名称(减去 .py
扩展名),再加上应用程序中的可调用名称。在我们的例子中,写作 wsgi:app
。
您还将指定要绑定到的接口和端口,以便应用程序将在公共可用接口上启动:
gunicorn --bind 0.0.0.0:5000 wsgi:app
您将收到以下类似的输出:
[2021-11-19 23:07:57 +0000] [8760] [INFO] Starting gunicorn 20.1.0
[2021-11-19 23:07:57 +0000] [8760] [INFO] Listening at: http://0.0.0.0:5000 (8760)
[2021-11-19 23:07:57 +0000] [8760] [INFO] Using worker: sync
[2021-11-19 23:07:57 +0000] [8763] [INFO] Booting worker with pid: 8763
[2021-11-19 23:08:11 +0000] [8760] [INFO] Handling signal: int
[2021-11-19 23:08:11 +0000] [8760] [INFO] Shutting down: Master
再次在您的网络浏览器中访问服务器的 IP 地址,并在末尾添加 :5000
:
http://your_server_ip:5000
您的应用程序输出将生成以下内容:
!Flask sample app
确认它正常运行后,在终端窗口中按下 CTRL + C
。
由于您现在已经完成了虚拟环境,因此请将其停用:
deactivate
任何 Python 命令现在将再次使用系统的 Python 环境。
接下来,创建 systemd 服务单元文件。创建一个 systemd 单元文件将允许 Ubuntu 的 init 系统在服务器启动时自动启动 Gunicorn 并提供 Flask 应用程序。
在 /etc/systemd/system
目录中创建一个以 .service
结尾的单元文件开始:
sudo nano /etc/systemd/system/myproject.service
在其中,从 [Unit]
部分开始,用于指定元数据和依赖项。在这里添加您服务的描述,并告诉 init 系统仅在达到网络目标后才启动此服务:
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target
接下来,创建一个 [Service]
部分。这将指定您希望进程在其中运行的用户和组。由于它拥有所有相关文件,因此请为该进程提供您的常规用户帐户所有权。还要将组所有权授予 www-data 组,以便 Nginx 可以与 Gunicorn 进程通信。请记住在此处用您自己的用户名替换用户名:
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target
[Service]
User=sammy
Group=www-data
接下来,映射工作目录并设置 PATH
环境变量,以便 init 系统知道进程的可执行文件位于您的虚拟环境中。还要指定启动服务的命令。此命令将执行以下操作:
- 启动 3 个工作进程(根据需要进行调整)
- 在项目目录中创建并绑定到一个 Unix 套接字文件
myproject.sock
- 设置
umask
值为007
,以便创建套接字文件以授予所有者和组的访问权限,同时限制其他访问权限 - 指定 WSGI 入口点文件名,以及该文件中的 Python 可调用项(
wsgi:app
)
Systemd 要求您提供 Gunicorn 可执行文件的完整路径,该文件已安装在您的虚拟环境中。
请记住用您自己的用户名和项目路径替换用户名和项目路径:
[Unit]
Description=Gunicorn 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/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
最后,添加一个 [Install]
部分。这将告诉 systemd 如果启用它以在启动时启动,则将此服务链接到什么。您希望此服务在常规多用户系统启动并运行时启动:
[Unit]
Description=Gunicorn 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/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
[Install]
WantedBy=multi-user.target
至此,您的 systemd 服务文件已完成。现在保存并关闭它。
现在启动您创建的 Gunicorn 服务:
sudo systemctl start myproject
然后启用它,以便在启动时启动:
sudo systemctl enable myproject
检查状态:
sudo systemctl status myproject
您将收到以下类似的输出:
● myproject.service - Gunicorn instance to serve myproject
Loaded: loaded (/etc/systemd/system/myproject.service; enabled; vendor preset
Active: active (running) since Fri 2021-11-19 23:08:44 UTC; 6s ago
Main PID: 8770 (gunicorn)
Tasks: 4 (limit: 1151)
CGroup: /system.slice/myproject.service
├─9291 /home/sammy/myproject/myprojectenv/bin/python3.6 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
├─9309 /home/sammy/myproject/myprojectenv/bin/python3.6 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
├─9310 /home/sammy/myproject/myprojectenv/bin/python3.6 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
└─9311 /home/sammy/myproject/myprojectenv/bin/python3.6 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
…
如果收到任何错误,请确保在继续教程之前解决它们。
第五步 — 配置 Nginx 代理请求
您的 Gunicorn 应用服务器现在应该已经启动并运行,等待在项目目录中的套接字文件上接收请求。接下来,通过对 Nginx 配置文件进行一些小的修改,配置 Nginx 将 Web 请求传递到该套接字。
首先,在 Nginx 的 sites-available
目录中创建一个新的服务器块配置文件。我们将其命名为 myproject
,以保持与本指南的其余部分一致:
sudo nano /etc/nginx/sites-available/myproject
打开一个服务器块,并告诉 Nginx 监听默认端口 80
。同时,告诉它使用此块来处理您服务器的域名的请求:
server {
listen 80;
server_name your_domain www.your_domain;
}
接下来,添加一个匹配每个请求的位置块。在此块中,包含指定一些需要设置的通用代理参数的 proxy_params
文件。然后使用 proxy_pass
指令将请求传递到您定义的套接字:
server {
listen 80;
server_name your_domain www.your_domain;
location / {
include proxy_params;
proxy_pass http://unix:/home/sammy/myproject/myproject.sock;
}
}
完成后保存并关闭文件。
要启用您创建的 Nginx 服务器块配置,将该文件链接到 sites-enabled
目录。您可以通过运行 ln
命令和 -s
标志来执行此操作,以创建一个符号链接或 软链接,而不是 硬链接:
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
将链接添加到该目录后,您可以测试语法错误:
sudo nginx -t
如果没有指示任何问题,重新启动 Nginx 进程以读取新配置:
sudo systemctl restart nginx
最后,再次调整防火墙。由于您不再需要通过端口 5000
访问,因此删除该规则:
sudo ufw delete allow 5000
然后允许 Nginx 服务器的完全访问:
sudo ufw allow 'Nginx Full'
现在,您应该能够在 Web 浏览器中导航到您服务器的域名:
http://your_domain
您的应用程序输出将显示在浏览器中:
!Flask sample app
如果遇到任何错误,请尝试检查以下内容:
sudo less /var/log/nginx/error.log
:检查 Nginx 错误日志。sudo less /var/log/nginx/access.log
:检查 Nginx 访问日志。sudo journalctl -u nginx
:检查 Nginx 进程日志。sudo journalctl -u myproject
:检查您的 Flask 应用的 Gunicorn 日志。
第六步 — 保护应用程序
为了确保服务器的流量保持安全,您应该为您的域名获取 SSL 证书。有多种方法可以做到这一点,包括从 Let’s Encrypt 获取免费证书、生成自签名证书,或者从其他提供商购买证书并按照《在 Ubuntu 18.04 中为 Nginx 创建自签名 SSL 证书的步骤 2 到 6》进行配置。出于快速性的考虑,我们将选择第一种选项。
首先,使用 snap
安装 Certbot:
sudo snap install --classic certbot
您的输出将显示 Certbot 的当前版本,并指示安装成功:
certbot 1.21.0 from Certbot Project (certbot-eff✓) installed
接下来,从 /usr/bin/
目录创建一个符号链接到新安装的 /snap/bin/certbot
可执行文件。这将确保 certbot
命令可以在您的服务器上正确运行:
sudo ln -s /snap/bin/certbot /usr/bin/certbot
Certbot 提供了通过插件获取 SSL 证书的各种方法。Nginx 插件将负责在必要时重新配置 Nginx 并重新加载配置。要使用此插件,请输入以下命令:
sudo certbot --nginx -d your_domain -d www.your_domain
这将使用 --nginx
插件运行 certbot
,并使用 -d
指定要为其颁发证书的名称。
如果这是您第一次运行 certbot
,系统将提示您输入电子邮件地址并同意服务条款。完成后,certbot
将与 Let’s Encrypt 服务器通信,请求为您的域名颁发证书。如果成功,您将收到以下输出:
成功接收到证书。
证书保存在:/etc/letsencrypt/live/jeanellehorcasitasphd.com/fullchain.pem
密钥保存在:/etc/letsencrypt/live/jeanellehorcasitasphd.com/privkey.pem
此证书将在 2022-03-03 到期。
这些文件将在证书更新时更新。
Certbot 已设置了一个后台定时任务,以自动更新此证书。
部署证书
已成功将证书部署到您的域名的 /etc/nginx/sites-enabled/myproject
已成功将证书部署到您的域名的 /etc/nginx/sites-enabled/myproject
恭喜!您已成功在 https://your_domain 和 https://your_domain 上启用了 HTTPS
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
如果您喜欢 Certbot,请考虑通过以下方式支持我们的工作:
* 向 ISRG / Let's Encrypt 捐赠:https://letsencrypt.org/donate
* 向 EFF 捐赠:https://eff.org/donate-le
如果您按照先决条件中的 Nginx 安装说明进行了安装,您将不再需要冗余的 HTTP 配置允许:
sudo ufw delete allow 'Nginx HTTP'
要验证配置,请再次使用 https://
导航到您的域名:
https://your_domain
您应该再次收到您的应用程序输出,以及您浏览器的安全指示器,指示网站已经得到了安全保护。
结论
在本指南中,您在 Python 虚拟环境中创建并保护了一个基本的 Flask 应用程序。您创建了一个 WSGI 入口点,以便任何支持 WSGI 的应用程序服务器都可以与其进行交互,然后配置了 Gunicorn 应用程序服务器来提供此功能。随后,您创建了一个 systemd 服务文件,以便在启动时自动启动应用程序服务器。您还创建了一个 Nginx 服务器块,将 Web 客户端流量传递给应用程序服务器,以中继外部请求,并使用 Let’s Encrypt 保护服务器的流量。
Flask 是一个极其灵活的框架,旨在为您的应用程序提供功能,而不会对结构和设计过于限制。您可以使用本指南中描述的通用堆栈来为您设计的 Flask 应用程序提供服务。
标签:Gunicorn,18.04,Flask,sudo,应用程序,myproject,Nginx,服务器 From: https://blog.csdn.net/rubys007/article/details/143277297