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. js apply() call() bind() 的使用

    bind ,call,apply 这三者都是用来改变函数的this对象的指向的. call和apply其实是同一个东西,区别只有参数不同. 其实call和apply ,只要你调用调用一个函数的时候就可 ...

  2. ssm框架之springMVC拦截器

    1拦截器概述 1.1什么是拦截器? springMVC中的拦截器(Interceptor)类似于servlet中的过滤器(Filter),它主要用于拦截用户请求并作相应的处理.例如通过拦截器可以进行权 ...

  3. 释放数据价值:DAYU数据运营新能力解读

    摘要:从比特到信息,这说的其实就是企业数字化转型,让数据的价值充分发挥出来,变成信息. 今天,企业对数据越来越重视,数据已经成为了企业新型的资产,甚至是核心资产,最近流传一句非常有意思的话:从比特到信 ...

  4. myeclipse前端界面乱码

    框起来的值默认的格式是ISO-8859-1,改为UTF-8

  5. 在微信公众号"码海"里学了一招:在update语句里使用case when 以避免多次更新导致的数据异常.

    需求:将emp表中工资大于一万的降到9成,工资少于一万的乘以1.2. 难点:如果分成两句update执行,在10000附近的值可能会执行两次. 钥匙:在update语句里采用case when,使更新 ...

  6. mysql jdbc连接时的小问题java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)

    这次重新修改老程序时出现了上面的错误,排查过后最终找到问题所在:root帐户默认不开放远程访问权限,所以需要修改一下相关权限. 打开MySQL目录下的my.ini文件(win10默认安装在C:\Pro ...

  7. 解决Maven的JDK版本问题

    在pom文件中添加以下代码 <build> <plugins> <plugin> <groupId>org.apache.maven.plugins&l ...

  8. 服务器搭建远程docker深度学习环境

    服务器搭建远程docker深度学习环境 本文大部分内容参考知乎文章 Docker+PyCharm快速搭建机器学习开发环境 搭建过程中出现ssh连接问题可以查看最后的注意事项 Docker Docker ...

  9. Spring源码系列(三)--spring-aop的基础组件、架构和使用

    简介 前面已经讲完 spring-bean( 详见Spring ),这篇博客开始攻克 Spring 的另一个重要模块--spring-aop. spring-aop 可以实现动态代理(底层是使用 JD ...

  10. 痞子衡嵌入式:IAR在线调试时设不同复位类型可能会导致i.MXRT下调试现象不一致(J-Link / CMSIS-DAP)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是IAR在线调试时设不同复位类型可能会导致i.MXRT下调试现象不一致. 做Cortex-M内核MCU嵌入式软件开发,可用的集成开发环境( ...