Flask 内置了简单的 Web 环境,让我们在开发的时候只需要专注于应用实现,而真正要在生产环境运行时这个简单的 Web 环境就不够用了,还需要一系列操作才能让 Web 应用高效的运行起来。现在记录一下在生产环境部署 Flask 应用的其中一套方案:Nginx + Gunicorn + Supervisor。

1. 准备

1.1 项目结构

我的项目结构类似这样, myapp 包是应用的主要代码,其中的初始化文件 init 提供了创建程序实例的工厂方法 create_app ,主目录下的 .flaskenv 和 .env 文件存储了一些 Flask 程序要用到的环境变量。

MyApp
|----myapp
| | __init__.py
| | ...
| .flaskenv
| .env
| ...

当然一个最简单的 Flask 应用可能类似下面这种结构也是可以的,我们只需要清楚自己最后的程序实例 app 的位置即可。

MyApp
| app.py
| ...

1.2 修改生产环境配置

这个配置写在 .flaskenv 文件里面比较方便,后面运行时从里面读取加载。

FLASK_ENV = production

1.3 在项目根目录创建 wsgi.py

创建这个文件的作用主要有两个:

  • 自行读取文件中定义的环境变量,因为后面用正式服务器运行时不会自动从文件中加载。
  • 导入程序实例,方便启动。
import os
from dotenv import load_dotenv from myapp import create_app # 读取环境变量
flaskenv_path = os.path.join(os.path.dirname(__file__), '.flaskenv')
env_path = os.path.join(os.path.dirname(__file__), '.env')
if os.path.exists(flaskenv_path):
load_dotenv(flaskenv_path)
if os.path.exists(env_path):
load_dotenv(env_path) # 如果是简单的单文件结构,这里直接 from app import app 也可
app = create_app()

2. 使用Gunicorn启动Flask应用

开发环境下使用flask run 命令或者程序中使用 app.run() 启动的是由 Werkzeug 提供的 WSGI 服务器,它的性能很弱,我们需要一个更健壮的WSGI服务器,也叫WSGI容器,主流选择是 uWSGIGunicorn ,也有其他像 GeventWaitress 等等,这里我们使用 Gunicorn,主要是简单易用且高效。

2.1 安装

Gunicorn 使用 pip 安装即可,若有用虚拟环境,在虚拟环境中安装。

pip install gunicorn

2.2 启动

Gunicorn 启动 Flask 程序需要指定包含程序实例的模块,还有其他参数设置例如工作进程数,一般为cpu核心数,监听地址,设置为 0.0.0.0:端口号 即可监听外网,这里我们只需监听本地地址,因为后面会用到 Web服务器 监听外网然后转发请求到本地地址。

# -w 6 工作线程数,相当于 --workers=6
# -b 127.0.0.1:8000 监听地址,相当于 --bind=127.0.0.1:8000
gunicorn -w 6 -b 127.0.0.1:8000 wsgi:app

3. 使用Supervisor管理进程

直接通过命令运行 Gunicorn 并不可靠,我们需要一个工具来自动在后台运行它并同时监控运行状态,自动重启等。

3.1 安装

sudo apt install supervisor

3.2 配置

全局配置文件在 /etc/supervisor/supervisord.conf,在同级 conf.d/ 目录下创建自己的程序配置myapp.conf,注意目录改成自己的目录,command 要使用正确的虚拟环境(如果有):

[program:myapp]
directory=/home/assassin/tmp/MyApp
stdout_logfile=/home/assassin/tmp/MyApp/supervisor.log
stderr_logfile=/home/assassin/tmp/MyApp/supervisor.log
command=/home/assassin/usr/miniconda3/envs/flask/bin/gunicorn -w 6 -b 127.0.0.1:8000 wsgi:app
user=assassin
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true

3.3 启动

重启 supervisor 服务来加载配置好的 WSGI 程序。

sudo service supervisor restart

查看程序运行状态:

sudo supervisorctl status

停止/启动程序:

sudo supervisorctl stop/start myapp

4. 使用Nginx提供反向代理

Gunicorn 这类WSGI服务器虽然内置了 Web 服务器,已经可以与客户端交换数据,但是不够健壮,更流行的方式是使用一个常规的 Web 服务器运行在前段为 WSGI 服务器提供反向代理,如Nginx,Apache等,这样做的好处有:

  • 提高处理静态文件的效率。Nginx可以对静态文件设置缓存,速度非常快。
  • 提高安全系数。避免直接暴露 WSGI 服务器。
  • 提高处理能力。缓冲请求,预处理,负载均衡等。

这样使用反向代理服务后,WSGI服务器只需要监听本地端口,由代理服务器监听外部端口,将请求转发到WSGI服务器。

4.1 安装

sudo apt install nginx

4.2 配置

新建 /etc/nginx/conf.d/myapp.conf 来配置代理服务

server {
listen 15535; # 监听15535端口来自外部的请求
server_name _; # 如果映射了域名,可以代替_ # 为HTTP规则 / 设置转发
location / {
proxy_pass http://127.0.0.1:8000; # 转发到本地端口
proxy_redirect off; # 重写一些请求首部
proxy_set_header Host $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;
} # 为 /static 静态资源请求设置转发,并指定缓存时间,这比从Flask中获取快得多
location /static {
alias /home/assassin/tmp/Bluelog/bluelog/static/;
expires 10d;
}
}

4.3 启动

使用 sudo nginx -t 来测试配置文件的正确性,没问题后便可以用 sudo service nginx restart 重启Nginx服务。此时访问主机地址的 15535 端口便可以访问到 Flask 应用。

5. 补充

  • Nginx 和 supervisor 安装后默认都是自启动的,如果不需要,可以使用如下命令(Ubuntu):
# 查看服务状态
service --status-all
# 查看自启
systemctl list-unit-files | grep enable
# 关闭自启
sudo systemctl disable nginx.service
sudo systemctl disable supervisor.service
# 打开自启
sudo systemctl enable nginx.service
sudo systemctl enable supervisor.service

Nginx+Gunicorn+Supervisor部署Flask应用的更多相关文章

  1. flask +gevent+nginx+Gunicorn+supervisor部署flask应用

    上篇   可以完美部署flask ,但是视乎在结合gevent+apscheduler 实现异步非阻塞后台和定时任务的时候视乎不是那么完美.请教了前辈,决定使用flask+gevent+nginx+g ...

  2. CentOS 下部署Nginx+Gunicorn+Supervisor部署Flask项目

    原本之前有一部分东西是在Windows Server,但是由于Gunicorn不支持Windows部署起来颇为麻烦.最近转战CentOS,折腾一段时间,终于简单部署成功.CentOS新手,作为一个总结 ...

  3. 2020最新nginx+gunicorn+supervisor部署基于flask开发的项目的生产环境的详细攻略

    本攻略基于ubuntu1804的版本,服务器用的华为云的服务器,python3(python2已经在2020彻底停止维护了,所以转到python3是必须的)欢迎加我的QQ6398903,或QQ群讨论相 ...

  4. 给我一台全新的服务器,使用nginx+gunicorn+supervisor部署django

    0.准备工作 在一台全新的服务器中新建用户以及用户的工作目录,之后的操作都以这个用户的身份进行,而不是直接用root. 举个栗子: 在服务器下新建用户rinka并赋予sudo权限 1) root登陆, ...

  5. Python基础 - Ubuntu+Nginx+uwsgi+supervisor部署Flask应用

    网上找了许多讲关于Flask应用部署的文章几乎都是一个helloworld的Demo,按照helloworld来部署都没问题,但实际项目部署时还是遇到了不少问题.在这里简单写下自己成功部署的过程,防止 ...

  6. flask部署:Ubuntu下使用nginx+uwsgi+supervisor部署flask应用

    之前一直用的Centos或者Red hat,自从使用Ubuntu后,发现Ubuntu使用起来更方便,自此爱上Ubuntu. 一.从github上下载flask应用 1.我已经成功将自己编写好的应用上传 ...

  7. Nginx+uwsgi+supervisor+Ubuntu+flask

    Nginx+uwsgi+supervisor+Ubuntu+flask Nginx+uwsgi+supervisor在Ubuntu上部署flask应用 网上找了许多讲关于Flask应用部署的文章几乎都 ...

  8. 学习大牛笔记nginx + gunicorn + supervisor

    安装 gunicorn pip install gunicorn pip 是一个重要的工具,python 用来管理包.还有一个最佳生产就是每次使用 pip 安装的库,都写入一个 requirement ...

  9. 在Mac上使用Nginx和FastCGI部署Flask应用

    最近在学习Flask,本文介绍一下如何部署Flask开发的应用,同时也学习一下Nginx的使用,这只是在Mac上的一个实验. 应用 这里使用的应用就是官方的文档中给出的Flaskr. 安装Nginx ...

随机推荐

  1. 06.深入学习redis replication的完整流程和原理

    一.replication的完整流程 slave配置master ip和port # slaveof <masterip> <masterport> slaveof 127.0 ...

  2. Picker 组件的设计与实现

    前言 今天的主题是 Picker 组件的设计与实现,Picker 组件是 NutUI 的一个拾取器组件,它用于显示一系列的值集合,用户可以滚动选择集合中一项,也可以支持多个系列的值集合供用户分别选择. ...

  3. Node.js 学习笔记之四:使用数据库

    这部分示例将示范SQLite3.MongoDB这两种不同类型的数据库在 Node.js 中的使用方法.首先,我们要在code目录下执行mkdir 06_database命令来创建用于存放这一组示例的目 ...

  4. myblogplus 第三期 如何更改你博客的图标,已实现 - mooling原创

    三言两语 博客的logo可以凸显你的blog的个性 不知道你有没有觉得博客园原始的那个小矿工不好看了呢 fromto 这才是个人博客的style! 为什么要写这篇文章 因为在博客园的“找找看”中,如果 ...

  5. 小程序开发-开发模式下关闭http域名校验

    小程序开发模式去掉域名校验 我们在开发小程序的时候如果用到其他网络地址,在小程序运行时调试器会输出 : http://www.example.com 不在以下 request 合法域名列表中,请参考文 ...

  6. 跟着尚硅谷系统学习Docker-【day02】

    day02-20200714   p9.docker阿里云配置   helloword   拉取镜像-运行-   拉取镜像如果从国外网站拉取辉比较慢,所以需要配置阿里云或者网易云得镜像仓库.   首先 ...

  7. 11.QT-ffmpeg+QAudioOutput实现音频播放器

    1.前言      由于QAudioOutput支持的输入数据必须是原始数据,所以播放mp3,WAV,AAC等格式文件,需要解封装后才能支持播放.      而在QT中,提供了QMediaPlayer ...

  8. 采用GitOps的11大原因

    Kubernetes允许我们单纯地使用声明性的配置文件来管理我们的应用部署和其他基础设施组件(例如,我们现在都是YAML开发者).这使我们能够把所有这些文件放到Git仓库中,然后把它挂到流水线上(Je ...

  9. apply用法

    result.push.apply(result, document.getElementsByTagName(tag)); 但是,这里为什么要用apply呢? 因为document.getEleme ...

  10. VMware安装Centos7并联网使用

    一.安装VMware VMwareworkstation官方下载地址: https://www.vmware.com/cn/products/workstation-pro/workstation-p ...