Flask + uWSGI + nginx + mysql + Docker-compose 搭建环境
Flask + uWSGI + nginx + mysql + Docker-compose 搭建环境
flask 已经能够简单的使用了,还没有部署过,这次再将其用Docker-compose编排一下,使得可以一句命令搭建生产环境。
相关概念
uWSGI是实现WSGI、uwsgi等协议的web服务器,而搭配nginx可以更好的做到负载均衡。而flask自带的支持WSGI协议的web服务器并不能很好的用作生产环境,只能在开发环境下使用了。
准备Flask代码
下面是一个简单的使用到mysql的flask小程序,数据库操作并没有什么实质性的操作,只要连接上了就可以了,而且在使用docker-compose之前,mysql并没有什么好说的。
/home/jrxnm/webapp/webapp.py
from flask import Flask, render_template_string
import pymysql
app = Flask(__name__)
@app.route("/")
def index():
try:
db = DbOperate()
except:
return render_template_string('<h1>Mysql Can not connect</h1>')
return render_template_string('<h1>Hello Flask !!!</h1>')
class DbOperate(object):
def __init__(self):
db = pymysql.connect('127.0.0.1', 'root', '123456', 'webapp')
if __name__ == "__main__":
app.run(debug=True,port=5555)
准备uWSGI
uWSGI是python实现的,pip安装就可以了。pip install uwsgi
当然我们也可以不需要nginx,直接使用uWSGI作为flask的web服务器,但uWSGI提供了socket接口,方便nginx接入。
uWSGI配置文件:uwsgi.ini
[uwsgi]
module = webapp:app
master = true
processes = 4
chdir = /home/jrxnm/webapp
socket = 127.0.0.1:8002
logto = /home/jrxnm/log/app.log
chmod-socket = 666
vacuum = true
chdir 指的是webapp.py的绝对地址,socket就是uWSGI留给nginx接入的接口(如果将socket一行改为http=:5000,就相当于flask直接用uWSGI作为服务器运行了),logto是日志地址,module指的是执行webapp.py文件中的app。
现在执行uwsgi --ini ./uwsgi.ini
uWSGI服务器就运行起来了。

当然uWSGI也可以直接用命令行启动,不必写入配置文件,只是每次都需要敲同样的配置。具体方法参考官方手册
准备nginx
ubuntu apt 安装就好了, apt install nginx
nginx 和 apache2 服务器配置方式差不多,如下为/etc目录下nginx部分分支图
nginx
├── conf.d
├── nginx.conf
├── sites-available
│ └── default
├── sites-enabled
├── uwsgi_params
我们可以看到,/etc/nginx/nginx.conf 是nginx的总配置文件,并且在其中include了如下两个文件夹

和apache一样sites-available文件夹是用来存放运行和暂不运行的配置文件,而sites-enabled则是存放运行的配置文件,而且sites-enabled中的配置文件大多是sites-available中配置文件的软链。
现在我们来写一个配置文件,这里只做最简单的配置:nginx.conf
server {
listen 80;
server_name 127.0.0.1;
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8002;
}
}
这里重点是include uwsgi_params;
和uwsgi_pass 127.0.0.1:8002;
前者确定使用uWSGI,后者确定uWSGI接口。
我们直接将nginx.conf添加到conf.d文件夹重启nginx服务器就好。
Flask + uWSGI + nginx
如果上面的uWSGI服务器运行成功,nginx服务器重启没有报错的话,那么此时在本机的80端口应该就可以看到我们的Flask程序跑起来了

使用docker-compose编排
docker容器是个好东西,一键配置环境,在这里我们也使用docker-compose搭建 Flask + uWSGI + nginx + mysql 的环境。
最终项目树
├── webapp
└── app.py
└── Dockerfile
└── uwsgi.ini
├── bak.sql
├── nginx.conf
docker-compose.yml 如下:
version: "3"
services:
webapp:
build: ./webapp
container_name: webapp
depends_on:
- mysql
volumes:
- ./app.log:/webapp/app.log
mysql:
image: mysql:5.7
environment:
- MYSQL_ROOT_PASSWORD=123456
volumes:
- ./bak.sql:/docker-entrypoint-initdb.d/bak.sql
nginx:
image: nginx
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- webapp
ports:
- "8888:80"
主要解释一下,每个service对应一个容器,使用build制定Dockerfile位置,使用image制定镜像名称。volumes将本地文件或者文件夹挂载到docker容器中,mysql容器挂载到/docker-entrypoint-initdb.d/
文件夹是因为官方实现的mysql镜像有初始化功能,在该文件夹的.sql和.sh文件将被执行。
webapp/Dockerfile
FROM python:3.6
ENV TZ=Asia/Shanghai
RUN mkdir /webapp
WORKDIR /webapp
COPY . /webapp
RUN pip install -r requirements.txt
CMD ["uwsgi", "--ini", "/webapp/uwsgi.ini"]
这个时候,Flask中连接数据库的host就需要改成mysql(与docker-compose.yml中的services名相同)
class DbOperate(object):
def __init__(self):
db = pymysql.connect('mysql', 'root', '123456', 'webapp')
nginx.conf改为:
server {
listen 80;
server_name 0.0.0.0;
location / {
include uwsgi_params;
uwsgi_pass webapp:8002;
}
}
uwsgi.ini改为:
[uwsgi]
module = webapp:app
master = true
processes = 4
chdir = /home/jrxnm/webapp
socket = :8002
logto = /home/jrxnm/log/app.log
chmod-socket = 666
vacuum = true
最后执行docker-compose up
就可以在本机8888端口看到flask程序运行了。
参考资料
https://www.cnblogs.com/franknihao/p/7202253.html
http://docs.jinkan.org/docs/flask/deploying/uwsgi.html#id1
https://blog.csdn.net/Reid_Lv/article/details/80109127