Flask项目Docker容器化部署原理与实现
本文将介绍Flask的部署方案:Flask + Nginx + uWSGI,并使用docker进行容器化部署,部署的实例来源 Flask开发初探,操作系统为ubuntu。
Flask系列文章:
- Flask开发初探
- WSGI到底是什么
- Flask源码分析一:服务启动
- Flask路由内部实现原理
部署方案
在开发时,我们使用flask run命令启动的开发服务器是werkzeug提供的,但是这种方式目的是为了开发,不能很好的扩展,不适合生产部署。生产部署,我们需要一个更强健,性能更高的WSGI服务器(关于WSGI,可参考WSGI到底是什么 ,常用的服务器有:uWSGI、Gunicorn等,本文以uWSGI举例。
像uWSGI这类WSGI服务器内置了Web服务器,所以我们不需要web服务器也可以与客户端交换数据,处理请求和响应,但是内置的web服务器不够强健,一般情况下都会使用一个常规的web服务器运行在前端,为WSGI服务器提供反向代理,web服务器选择Nginx,Nginx会把外部的请求转发给uWSGI处理,接收到响应后再返回给客户端,这样做的好处有:
- 提高静态文件的效率,因为Nginx处理静态文件的速度非常快
- 提升系统安全性,避免直接暴露WSGI服务器
- 提升程序处理能力,通过设置反向代理,配置负载均衡可以实现。
uWSGI配置
在使用uwsgi部署flask应用时,一定要记得将app.run()方法放在if __name__ == '__main__':
内部或者单独文件内,这样就可以保证其不会被调用,从而不会启动本地服务器。
uwsgi是一个服务器,使用前一定要安装:
pip install uwsgi
配置文件:
socket=/tmp/app.sock
chmod-socket=666
pidfile=/etc/nginx/uwsgi.pid
chdir=/home/**/mygithub/learn_flask/app
master=true
wsgi-file=serve.py
http=127.0.0.1:8005
callable=app
processes=8
threads=4
lazy-apps=true
对所配置的参数进行说明:
- callable:Flask项目的实例名称
- module:可调用对象的名称
- processes:开启多少个子进程处理请求。
- threads:每个进程的线程数
更多参数详情可见:uwsgi中文文档
在命令行中启动uwsgi服务器:
uwsgi --ini uwsgi.ini
在浏览器中输入 http://127.0.0.1:8005
,可以验证服务启动。
nginx配置
安装nginx:
apt-get install nginx
启动nginx:
service nginx start
重启
service nginx restart
nginx配置:
server{
listen 8080;
server_name localhost;
access_log /var/log/nginx/app_access.log;
error_log /var/log/nginx/app_error.log;
location / {
include uwsgi_params;
uwsgi_pass unix:/tmp/app.sock
}
}
nginx配置文件nginx.conf通过include引用了conf.d和site_enabled这两个文件夹中的配置文件,所以我们可将配置文件放在这两个路径任意一处。
重启nginx和uwsgi,在浏览器中输入 http://127.0.0.1:8088
,可以验证服务启动。
这样,就完成基础的nginx+uwsgi完成了Flask的部署。
容器化部署
接下来,介绍使用docker进行容器化部署。
docker配置
建议了解docker基本操作,首先,创建Dockerfile:
FROM ubuntu:16.04
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/Shanghai" > /etc/timezone
RUN apt update && apt install -y iputils-ping python3 python3-pip python3-tk libffi-dev libssl-dev
RUN apt install -y nginx && pip3 install uwsgi
ADD ['./', "/app"]
ADD ['./build', "/app"]
WORKDIR /app
RUN pip3 install -r requirements.txt
RUN chmod + x start_script.sh
CMD ['/start_script.sh']
注意:
- 该镜像的基础镜像为ubuntu:16.04,可自行docker pull
- 编写服务启动脚本start_script.sh
ln -s /app/nginx.conf /etc/nginx/conf.d/
nginx && uwsgi --ini uwsgi.ini
python3 serve.py
使用命令:
docker build -t image .
以上,就打包完成了镜像 (imagename),接下来执行docker run -d --name test imagename
启动容器,执行docker ps -a
可以看到刚才启动的容器,执行docker logs -f
可查看日志。
另外,推荐使用k8s对docker容器进行编排管理,具体使用后续博客介绍。
代码可参照:my github
- VIM常见用法总结
- Spring Cloud构建微服务架构:服务消费者
- android微信登录,分享
- 注册会计师带你用Python进行探索性风险分析(二)
- Android监听自身卸载,弹出用户反馈调查
- Spring Boot 1.5.x新特性:动态修改日志级别
- XMPP客户端库Smack 4.0.6版开发之二
- Spring Cloud实战小贴士:版本依赖关系
- 如何优雅的用Python做接口自动化测试
- 忘记oracle的sys用户密码怎么修改以及Oracle 11g 默认用户名和密码
- hibernate链接数据库链接池c3p0配置
- Oracle中session和processes的设置
- ssh相关原理学习与常见错误总结
- PyQt5 GUI应用程序工具包入门(1)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- AndroidStudio项目打包成jar的简单方法
- 浅谈React Native打包apk的坑
- Android 设置主题实现点击波纹效果的示例
- 更新Android Studio 3.0碰到的问题小结
- android实现一个图片验证码倒计时功能
- Android添加glide库报错Error:Failed to resolve:com.android.support:26.0.2的解决
- Android多线程下载示例详解
- 详解Android Gradle插件3.0挖坑日记
- Android开发之拼音转换工具类PinyinUtils示例
- Android多线程断点续传下载示例详解
- Android设备与外接U盘实现数据读取操作的示例
- [Alibaba-ARouter]浅谈简单好用的Android页面路由框架
- android屏幕圆角实现方法的示例代码
- Android开发中日期工具类DateUtil完整实例
- Android模仿实现微博详情页滑动固定顶部栏的效果实例