Nginx+Gunicorn+Supervisor部署Flask应用
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容器,主流选择是 uWSGI 和 Gunicorn ,也有其他像 Gevent,Waitress 等等,这里我们使用 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应用的更多相关文章
- flask +gevent+nginx+Gunicorn+supervisor部署flask应用
上篇 可以完美部署flask ,但是视乎在结合gevent+apscheduler 实现异步非阻塞后台和定时任务的时候视乎不是那么完美.请教了前辈,决定使用flask+gevent+nginx+g ...
- CentOS 下部署Nginx+Gunicorn+Supervisor部署Flask项目
原本之前有一部分东西是在Windows Server,但是由于Gunicorn不支持Windows部署起来颇为麻烦.最近转战CentOS,折腾一段时间,终于简单部署成功.CentOS新手,作为一个总结 ...
- 2020最新nginx+gunicorn+supervisor部署基于flask开发的项目的生产环境的详细攻略
本攻略基于ubuntu1804的版本,服务器用的华为云的服务器,python3(python2已经在2020彻底停止维护了,所以转到python3是必须的)欢迎加我的QQ6398903,或QQ群讨论相 ...
- 给我一台全新的服务器,使用nginx+gunicorn+supervisor部署django
0.准备工作 在一台全新的服务器中新建用户以及用户的工作目录,之后的操作都以这个用户的身份进行,而不是直接用root. 举个栗子: 在服务器下新建用户rinka并赋予sudo权限 1) root登陆, ...
- Python基础 - Ubuntu+Nginx+uwsgi+supervisor部署Flask应用
网上找了许多讲关于Flask应用部署的文章几乎都是一个helloworld的Demo,按照helloworld来部署都没问题,但实际项目部署时还是遇到了不少问题.在这里简单写下自己成功部署的过程,防止 ...
- flask部署:Ubuntu下使用nginx+uwsgi+supervisor部署flask应用
之前一直用的Centos或者Red hat,自从使用Ubuntu后,发现Ubuntu使用起来更方便,自此爱上Ubuntu. 一.从github上下载flask应用 1.我已经成功将自己编写好的应用上传 ...
- Nginx+uwsgi+supervisor+Ubuntu+flask
Nginx+uwsgi+supervisor+Ubuntu+flask Nginx+uwsgi+supervisor在Ubuntu上部署flask应用 网上找了许多讲关于Flask应用部署的文章几乎都 ...
- 学习大牛笔记nginx + gunicorn + supervisor
安装 gunicorn pip install gunicorn pip 是一个重要的工具,python 用来管理包.还有一个最佳生产就是每次使用 pip 安装的库,都写入一个 requirement ...
- 在Mac上使用Nginx和FastCGI部署Flask应用
最近在学习Flask,本文介绍一下如何部署Flask开发的应用,同时也学习一下Nginx的使用,这只是在Mac上的一个实验. 应用 这里使用的应用就是官方的文档中给出的Flaskr. 安装Nginx ...
随机推荐
- AD18 PCB中添加中文字符串显示乱码问题解决
该问题是由于字符串的自体类型设置问题,AD默认是[stroke],我们点击[TrueType]即可正常显示.PS:AD18搞啥呢,默认显示输入内容不行吗,找半天!!!
- HMM隐马尔可夫模型来龙去脉(二)
目录 前言 预备知识 一.估计问题 1.问题推导 2.前向算法/后向算法 二.序列问题 1.问题推导 2.维特比算法 三.参数估计问题 1.问题推导 2.期望最大化算法(前向后向算法) 总结 前言 H ...
- P4609 建筑师
题目描述 小 Z 是一个很有名的建筑师,有一天他接到了一个很奇怪的任务:在数轴上建 n 个建筑,每个建筑的高度是 1 到 n 之间的一个整数. 小 Z 有很严重的强迫症,他不喜欢有两个建筑的高度相同. ...
- 面试【JAVA基础】Web与网络
1.转发与重定向的区别 转发是服务器请求资源,服务器直接访问目标地址url,把响应内容返回给浏览器. 重定向根据服务器返回的状态码重新请求地址. 转发是服务器行为,重定向是客户端行为. 转发显示的ur ...
- CTF常见源码泄漏总结
.hg源码泄漏 漏洞成因: hg init的时候会生成.hge.g.http://www.am0s.com/.hg/ 漏洞利用:工具:dvcs-ripperrip-hg.pl -v -u http:/ ...
- 【MySQL】我这样分析MySQL中的事务,面试官对我刮目相看!!
写在前面 相信大部分小伙伴在面试过程中,只会针对面试官提出的表面问题来进行回答.其实不然,面试官问的每一个问题都是经过深思熟虑的,面试的时间相对来说也是短暂的,面试官不可能在很短的时间内就对你非常了解 ...
- Java反射(一)
什么是反射? 在程序的运行过程中,可以动态的创建对象. 反射的基石是什么? 字节码对象是反射的基石.字节码对象:Java类文件通过javac进行编译后生成的xxx.class文件,此文件由jvm加载至 ...
- Linux系统小知识
换Linux系统快半年了,刚开始总是碰到各种各样的问题,虽然斗解决了,由于没有记录,过一段时间就忘了,故在这里记录一下. 选择国内镜像源: Manjaro有一个很好用的命令rankmirrors.ra ...
- Serverless 初体验:快速开发与部署一个Hello World(Java版)
昨天被阿里云的这个酷炫大屏吸引了! 我等85后开发者居然这么少!挺好奇到底什么鬼东西都是90.95后在玩?就深入看了一下. 这是一个关于Serverless的体验活动,Serverless在国内一直都 ...
- python之csrf简介
django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成.而对于django中设置防跨站请求伪造功能有分为全 ...