Docker在手,天下我有,在Win10系统下利用Docker部署Gunicorn+Flask打造独立镜像

简介: 书接上回,之前一篇:[Win10环境下使用Flask配合Celery异步推送实时/定时消息(Socket.io)/2020年最新攻略](https://v3u.cn/a_id_163),阐述了如何使用Celery异步推送Websocket消息,现在我们利用Docker将这个完整项目部署起来,为什么用Docker呢?原因很简单,这种容器技术可以将整个项目用单个容器装起来,仅仅只需要维护一个简单的配置文件就告诉电脑每次部署要把什么东西装进容器,甚至把这个过程自动化,部署流程就会变得简单、方便。

书接上回,之前一篇:Win10环境下使用Flask配合Celery异步推送实时/定时消息(Socket.io)/2020年最新攻略,阐述了如何使用Celery异步推送Websocket消息,现在我们利用Docker将这个完整项目部署起来,为什么用Docker呢?原因很简单,这种容器技术可以将整个项目用单个容器装起来,仅仅只需要维护一个简单的配置文件就告诉电脑每次部署要把什么东西装进容器,甚至把这个过程自动化,部署流程就会变得简单、方便。

简单理解就是Docker的镜像就类似《精灵宝可梦》中小智手里的精灵球,我们的项目就类似那些宠物小精灵,当我们开发完毕就可以利用DockerFile对项目进行打包制作成镜像(小精灵被吸入精灵球),部署时就可以理解为小精灵被释放出来进行战斗(通过打包好的镜像运行容器),而Docker的仓库则提高了镜像的便捷性,可以让我们随时随地只要联网就可以使用自己的镜像(相当于小智不用随身携带精灵球,而是通过网络随时下载需要的精灵球)。

同时Docker其强大的跨平台特性,可以让我们在任何系统下部署项目,包括经常令人诟病的Windows,值得一提的是本次在Win10下部署项目的流程同样适用于Centos、Mac os、Ubuntu等系统,其兼容性可见一斑。

关于Win10如何折腾和配置Docker,请参照这篇文章:win10系统下把玩折腾DockerToolBox以及更换国内镜像源(各种神坑)

首先简单看一下项目结构:

manage.py是项目的入口文件,这里我们利用Sockert.io让Flask支持Websocket

from flask import Flask  
from flask_sqlalchemy import SQLAlchemy  
import pymysql  
from flask import request,jsonify  
from flask_cors import CORS  
from flask_socketio import SocketIO,send,emit,join_room, leave_room  
import urllib.parse  
import user_view  
  
from celery import Celery  
from datetime import timedelta  
  
pymysql.install_as_MySQLdb()  
   
app = Flask(__name__)  
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:root@localhost:3306/md"  
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True  
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True  
  
app.config['BROKER_URL'] = 'redis://localhost:6379'  
app.config['CELERY_RESULT_BACKEND'] = 'redis://localhost:6379'  
app.config['CELERY_ACCEPT_CONTENT'] = ['json', 'pickle']  
app.config['REDIS_URL'] = 'redis://localhost:6379'  
app.config['JSON_AS_ASCII'] = False  
  
CORS(app,cors_allowed_origins="*")  
  
  
app.register_blueprint(user_view.user)  
  
db = SQLAlchemy(app)  
  
socketio = SocketIO(app,cors_allowed_origins='*',async_mode="threading",message_queue=app.config['CELERY_RESULT_BACKEND'])  
  
  
celery = Celery(app.name)  
celery.conf.update(app.config)  
  
  
celery.conf.CELERYBEAT_SCHEDULE = {  
          
        "test":{  
            "task":"get_cron",  
            "schedule":timedelta(seconds=10)  
        }  
  
}  
  
  
  
  
@celery.task(name="get_cron")  
def get_cron():  
      
    get_sendback.delay()  
      
  
@celery.task()  
def get_sendback():  
      
    socketio.emit('sendback','message',broadcast=True)  
  
@app.route('/task')  
def start_background_task():  
    get_sendback.delay()  
    return '开始'  
   
  
@app.route('/',methods=['GET','POST',"PUT","DELETE"])  
def hello_world():  
    #res = db.session.execute("insert into user (`username`) values ('123') ")  
  
    # res = db.session.execute(" select id,username from user ").fetchall()  
  
    # data = request.args.get("id")  
  
    # #data = request.form.get("id")  
  
    # print(data)  
  
    # print(res)  
  
    # #return 'Hello Flask'  
    # return jsonify({'result': [dict(row) for row in res]})  
  
    return jsonify({'message':'你好,Docker'})  
  
  
@socketio.on('join')  
def on_join(data):  
    username = 'user1'  
    room = 'room1'  
    join_room(room)  
    send(username + ' has entered the room.', room=room)  
  
@socketio.on('message')  
def handle_message(message):  
    message = urllib.parse.unquote(message)  
    print(message)  
    send(message,broadcast=True)  
  
@socketio.on('connect', namespace='/chat')  
def test_connect():  
    emit('my response', {'data': 'Connected'})  
  
@socketio.on('disconnect', namespace='/chat')  
def test_disconnect():  
    print('Client disconnected')  
   
@app.route("/sendback",methods=['GET'])  
def sendback():  
  
    socketio.emit('sendback','message')  
  
    return 'ok'  
   
if __name__ == '__main__':  
  
    socketio.run(app,debug=True,host="0.0.0.0",port=5000)

接下来使用Gunicorn+gevent来运行Flask项目,Gunicorn服务器作为wsgi app的容器,能够与各种Web框架兼容(flask,django等),得益于gevent等技术,使用Gunicorn能够在基本不改变wsgi app代码的前提下,大幅度提高wsgi app的性能。那到底怎么提升性能?说简单点,Gunicorn 默认的网络模型是 select ,当我们把worker 替换成 gevent 后,则改为 epoll 监听模型,关于select、poll、epoll请参照这篇文章:关于Tornado:真实的异步和虚假的异步,这里不再赘述。

安装相应的库

pip install gunicorn gevent --user

编辑项目目录下的gunicorn.conf.py

workers = 3    # 进程数  
worker_class = "gevent"   # 异步模式  
bind = "0.0.0.0:5000"

由于Gunicorn并不支持Windows环境,所以只需要写好配置,不需要运行。

编辑项目目录下的requirements.txt文件,这里面都是我们项目所依赖的库

flask==1.0.2  
flask-cors  
flask-socketio  
flask-sqlalchemy  
pymysql  
celery  
gunicorn  
gevent  
redis==3.3.11

随后在项目目录下创建一个 Dockerfile 文件,这个文件可以理解为打包镜像的脚本,你需要这个镜像做什么,就把任务写到脚本中,Docker通过执行这个脚本来打包镜像

FROM python:3.6  
WORKDIR /Project/myflask  
  
COPY requirements.txt ./  
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple  
  
COPY . .

ENV LANG C.UTF-8

CMD ["gunicorn", "manage:app", "-c", "./gunicorn.conf.py"]

可以看到,我们项目的镜像首先基于python3.6这个基础镜像,然后声明项目目录在/Project/myflask中,拷贝依赖表,之后安装相应的依赖,这里在安装过程中我们指定了国内的源用来提高打包速度,最后利用gunicorn运行项目,值得一提的是,ENV LANG C.UTF-8是为了声明Docker内部环境中的编码,防止中文乱码问题。

最后我们就可以愉快的打包整个项目了,在项目根目录下执行

docker build -t 'myflask' .

此时看到Docker通过读取Dockerfile文件来下载所需的基础镜像和依赖库,这里一定要指定Docker的下载源,否则速度会非常缓慢,打包好的镜像文件大概有1g左右。

下载结束之后,可以看到myflask这个镜像已经静静躺在镜像库中了,运行

docker images

命令来查看

然后我们就可以利用这个镜像来通过容器跑Flask项目了,运行命令

docker run -it --rm -p 5000:5000 myflask

这里的命令是通过端口映射把docker内部的端口5000映射到宿主机的5000端口上,后面的参数是镜像名称。我们看到,在Win10下,已经不可思议的通过Gunicorn把Flask跑起来了,这在之前没有Docker技术之前是不可想象的。

通过网址访问一下,这里注意一点,就是Windows系统下,访问Docker容器需要通过分配的ip来访问,而不是我们常用的localhost。

完全没有任何问题。

结语:到这里我们的 Docker+Flask + Gunicorn就部署完毕了,将这个镜像上传Dockerhub仓库,在任何时间、任何地点、任何系统上,只要连着网、只要我们想,就都可以在短短1分钟之内部署好我们的项目,这就是Docker技术对开发人员最好的馈赠。最后奉上项目地址:https://gitee.com/QiHanXiBei/myflask

相关文章
|
Ubuntu 关系型数据库 MySQL
在Ubuntu系统的Docker上安装MySQL的方法
以上的步骤就是在Ubuntu系统的Docker上安装MySQL的详细方法,希望对你有所帮助!
1468 12
|
监控 关系型数据库 MySQL
zabbix7.0.9安装-以宝塔安装形式-非docker容器安装方法-系统采用AlmaLinux9系统-最佳匹配操作系统提供稳定运行环境-安装教程完整版本-优雅草卓伊凡
zabbix7.0.9安装-以宝塔安装形式-非docker容器安装方法-系统采用AlmaLinux9系统-最佳匹配操作系统提供稳定运行环境-安装教程完整版本-优雅草卓伊凡
1188 30
|
Ubuntu Linux Docker
如何在Ubuntu 20.04系统中安装Docker
安装 Docker 引擎的步骤如下:首先更新系统包索引 (`sudo apt update`),安装必要依赖包 (`apt-transport-https` 等),添加 Docker 官方 GPG 密钥及 APT 仓库。接着再次更新包索引并安装 Docker 引擎及相关工具 (`docker-ce` 等)。最后启动 Docker 服务并设置开机自启,通过 `docker --version` 和运行测试容器 (`sudo docker run hello-world`) 验证安装是否成功。
5518 0
|
负载均衡 网络协议 算法
Docker容器环境中服务发现与负载均衡的技术与方法,涵盖环境变量、DNS、集中式服务发现系统等方式
本文探讨了Docker容器环境中服务发现与负载均衡的技术与方法,涵盖环境变量、DNS、集中式服务发现系统等方式,以及软件负载均衡器、云服务负载均衡、容器编排工具等实现手段,强调两者结合的重要性及面临挑战的应对措施。
617 4
|
存储 Linux Docker
centos系统清理docker日志文件
通过以上方法,可以有效清理和管理CentOS系统中的Docker日志文件,防止日志文件占用过多磁盘空间。选择合适的方法取决于具体的应用场景和需求,可以结合手动清理、logrotate和调整日志驱动等多种方式,确保系统的高效运行。
1684 2
|
人工智能 数据安全/隐私保护 虚拟化
Docker部署MaxKB详细步骤(window系统)
这篇文章详细介绍了如何在Windows系统上使用Docker部署MaxKB,并提供了从安装Docker到运行MaxKB容器的详细步骤,以及如何通过浏览器访问和配置MaxKB来使用ollama和llama3模型进行问答。
4648 1
Docker部署MaxKB详细步骤(window系统)
|
Ubuntu jenkins 持续交付
Ubuntu系统 用docker安装jenkins
Ubuntu系统 用docker安装jenkins
|
安全 Ubuntu Shell
深入挖掘Debian系统中安装Docker
【8月更文挑战第21天】在Debian系统中安装Docker需按步骤操作:首先确保软件包更新,执行`sudo apt update`并安装必要软件包支持HTTPS;接着添加Docker官方GPG密钥以验证包的完整性和安全性;然后设置Docker稳定版仓库,通过`tee`命令配置仓库文件;再更新软件包索引;最后安装Docker Engine并通过运行测试容器确认安装成功。此指南适用于多数Debian版本,如遇问题请查阅官方文档。
1213 0
|
缓存 Kubernetes 数据中心
在Docker中,如何控制容器占用系统资源(CPU,内存)的份额?
在Docker中,如何控制容器占用系统资源(CPU,内存)的份额?
|
NoSQL 数据可视化 Linux
一文教会你如何在Linux系统中使用Docker安装Redis 、以及如何使用可视化工具连接【详细过程+图解】
这篇文章详细介绍了如何在Linux系统中使用Docker安装Redis,并提供了使用可视化工具连接Redis的步骤。内容包括安装Redis镜像、创建外部配置文件、映射文件和端口、启动和测试Redis实例、配置数据持久化存储,以及使用可视化工具连接和操作Redis数据库的过程。