使用Flask+nginx+uwsgi+Docker部署pyth
本文记录自己在服务器上部署flask+python应用的实现过程,涉及的内容如下:
Flask、nginx和uwsgi之间的关系
从零开始使用Flask+nginx+uwsgi+Docker部署一个python应用
1. Flask、nginx和uwsgi之间的关系
客户端向服务器发送一个http请求,一般要经过下面三个阶段:
web服务器:用于接收客户端请求,并向客户端返回响应
web框架:用于对客户端的请求进行相应的处理,web框架也直接调用了我们自己编写的处理程序
WSGI协议:WSGI全称为Web Server Gateway Interface,它定义了web服务器和web框架之间相互交互的接口规范,只要web服务器和web框架满足WSGI协议,那么不同框架和服务器之间就可以任意搭配。要注意的是WSGI只适用于python语言

理解了上述内容,再来看Flask、nginx和uwsgi就比较简单:
nginx就是一个web服务器
Flask就是一个web框架,常用的其他web框架还有Django
uwsgi与WSGI一样,是一种通信协议。首先要说明,uWSGI是一个web服务器,它实现了WSGI、uwsgi、http等协议,其作用就是把HTTP协议转化成语言支持的网络协议,用于处理客户端请求,并向客户端返回响应。这里的uwsgi则是uWSGI服务器的独占协议(只适用于uWSGI服务器?),与WSGI是两种不同的协议
通过上面的描述中可以得出,uWSGI+Flask就可以实现一个完整的web服务,似乎不需要Nginx服务器。
当一个服务访问量过大时,我们可能会考虑多部署几台web服务器,这几台web服务器都可以处理客户端请求,但问题是如何将客户端请求分发到各个web服务器上?这就是Nginx的作用->反向代理服务器。
正向代理服务器(Proxy Server):如下图所示,用于代理客户端请求来访问外部网络信息,这种方式可以隐藏客户端真实IP,突破访问限制,保护客户端安全,VPN就是这种原理。

反向代理服务器(Reverse Proxy Server):反向代理服务器的功能是代理服务器接收客户端发来的请求,转发到相应的web服务器上进行处理,并将结果返回给客户端,反向代理服务器相当于是代理web服务器而不是客户端。

上图中的web服务器可以视为是uWSGI服务器,而反向代理服务器就相当于是nginx服务器,它具有强大的反向代理和负载均衡功能,可以平衡集群中各个服务器的负载,并且高效稳定。
综上,我们所使用的Flask+nginx+uwsgi部署python应用,客户端的每一次请求都要经过如下流程:

2. Docker部署python应用的整体框架
下图是一个简单的示意图,其中外侧粗线框矩形表示我们的服务器,内部各个小矩形分别代表了Flask Docker和Nginx Docker。
通过配置,我们将服务器的80端口映射到Nginx Docker的80端口,Nginx Docker会处理到达80端口的相关http请求。
通过配置,我们开放Flask Docker的8080端口,并配置Nginx Docker将相关的http请求通过8080端口发送到Flask Docker上,具体示意图如下:

以下内容几乎全部来自Building a Flask app with Docker | Learning Flask Ep. 24,自己按照这篇博客的步骤成功部署了自己的python应用,这里对相关内容进行更加详细的解释。
整个项目的文件结构如下:

配置uWSGI服务器:
相关uwsgi.ini文件内容如下:

module填写manage.py,wsgi-file填写manage.py(指定要加载的WSGI文件,也即包含Flask实例(app)的文件名称);socket:填写端口,指定socket文件,也可以指定为127.0.0.1:5000,用于配置监听特定端口的套接字;用于Nginx中uwsgi_pass代理监控的地址;
配置nginx服务器:

配置Docker:
flask/Dockerfile

nginx/Dockerfile

配置docker-compose:
通过配置docker-compose.yml文件,可以同时build和启动多个容器

使用:
# 在docker-compose.yml所在目录执行该命令, 生成镜像文件(可以直接用docker-compose up --build生成和启动镜像一起)
docker-compose build
# 启动容器docker-compose up
# 列出正在运行的镜像
docker-compose images

# 列出正在运行的容器
docker-compose ps

# 停止服务
docker-compose stop containerID
通过以上配置,可以实现在内网127.0.0.1或公网IP上通过http访问自己写的python应用程序。
Reference
https://www.cnblogs.com/vh-pg/p/11731637.html
https://pythonise.com/series/learning-flask/building-a-flask-app-with-docker-compose