【flask+gunicorn+docker】创建简单flask项目并部署到docker容器中

创建简单flask项目并部署到docker容器中

需求:
1.将lark的通知方式API重新封装成更接近需求的API
2.对接口API提供请求服务

选择的实现方式:
1.编写相关函数,主要是以请求lark的api为主体实现的
2.选择flask编写API
3.使用gunicorn + gevent启动flask服务
4.将服务封装到docker镜像中

本文重点:
1.如何快速创建简单的flask项目
2.如何使用gunicorn启动flask服务
3.docker封装运行相关细节

基础介绍

  • Flask :python最流行的两个框架之一(django、flask),轻量级是最大的特点
  • Gunicorn:只熟悉熟悉用 java 或者 PHP 做开发的可能对 python 的部署一开始不太理解,Flask应用是一个符合WSGI规范的Python应用,不能独立运行(类似app.run的方式仅适合开发模式),需要依赖其他的组件提供服务器功能。
  • gevent:gunicorn 默认使用同步阻塞的网络模型(-k sync),对于大并发的访问可能表现不够好,我们很方便地顺手套一个gevent来增加并发量
  • Docker:容器,可以理解成一个“黑盒”。在项目变得庞大以后,往往我们会疲于管理整个项目的部署和维护。如果我们将整个项目用一个“容器”装起来,那么我们仅仅只用维护一个配置文件告诉计算机每次部署要把什么东西装进“容器”,甚至借用一些工具把这个过程自动化,部署就会变得很方便。

本段转载自:Flask + Docker 无脑部署新手教程,也是对我帮助最大的一篇博客,言简意赅,推荐阅读。

1. 创建简单的flask项目

由于不涉及数据库相关,我们可以直接在根目录下添加一个app.py文件:

# ./app.py
from gevent import monkey
monkey.patch_all()

from flask import Flask
from flask_cors import CORS
from lark_api import lark_api

# 创建Flask对象
app = Flask(__name__,
            template_folder="public",
            static_folder="public",
            static_url_path="/")
# 将在其他文件 lark_api.py 声明的蓝图 lark_api 在 app 上进行注册
app.register_blueprint(lark_api)
# 跨域请求
CORS(app, supports_credentials=True, origins="*")

# 这里是为了方便后续测试服务是否跑起来
@app.route('/')
def HelloDockerFlask():
    return 'Hello Docker Flask!'


if __name__ == "__main__":
    app.run(debug=True)

lark_api.py中蓝图的注册方式和api的声明实现,这里只是简单举个例子:

from flask import Blueprint
# 创建蓝图对象
lark_api = Blueprint("lark_api", __name__)
# API声明:分别是自定的url和请求方式
@lark_api.route("/api/lark/card_message", methods=["POST"])
def card_message():
	## TODO

切到根目录下,终端运行以下指令,就可以运行flask自带的web服务了

python app.py

在这里插入图片描述
可以看到成功启动服务,但是flask自带的web服务比较弱,关闭终端或者超过时延,服务就会被关闭,因此只适合开发测试,不适合生产部署,因此我们后面使用gunicorn启动flask服务。

2. 使用 gunicorn+gevent 启动flask服务

通过pip可以快速安装

pip install gunicorn gevent

PS:需要注意的是,目前gunicorn只能运行在linux环境中,不支持windows平台。
我们在根目录下新建gunicorn.conf.py文件

# ./gunicorn.conf.py
workers = 5    # 定义同时开启的处理请求的进程数量,根据网站流量适当调整
worker_class = "gevent"   # 采用gevent库,支持异步处理请求,提高吞吐量
bind = "0.0.0.0:3000" # 设置端口,这里注意要设置成0.0.0.0,如果设置为127.0.0.1的话就只能本地访问服务了

创建好gunicorn.conf.py后,我们就可以通过gunicorn启动flask服务了

gunicorn app:app -c gunicorn.conf.py

第一个app表示app.py文件;第二个app表示创建的flask对象。

3. 使用 docker 封装flask服务

(1) Dockerfile的编写

根目录下创建Dockerfile文件,内容:

# 基于的基础镜像,这里使用python,开发版本是 3.x ,基础镜像也写 3.x 就可以,这样可以保持版本一致,避免 Python 版本差异带来的问题
FROM python:3.10 
# /app 是要部署到服务器上的路径
WORKDIR /app
# Docker 避免每次更新代码后都重新安装依赖,先将依赖文件拷贝到项目中
COPY requirements.txt requirements.txt
# 执行指令,安装依赖
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
# COPY指令和ADD指令功能和使用方式类似。只是COPY指令不会做自动解压工作。
# 拷贝项目文件和代码
COPY . .
# 执行指令,字符串间是以空格间隔
CMD ["gunicorn", "app:app", "-c", "./gunicorn.conf.py"]

PS:这里我踩了一个坑是FROM python:3.10 开始将‘python’大写了,注意这里必须小写,否则后续build docker会失败,我推测除了FROM其他字段也是一样需要小写。

(2) 创建docker镜像

docker build -t 'noticedemo' .

noticedemo是创建的镜像名称,可以自行修改。
需要注意的是这个过程需要一点时间,首次创建需要拉取基础镜像,并且安装依赖也需要时间。
构建完成之后,通过如下命令查看镜像列表,可以发现 noticedemo显示在其中

docker images

(3) 启动容器运行docker镜像

生产环境运行(以daemon方式运行)

docker run -d -p 3000:3000 noticedemo

-d:以daemon方式运行
-p:指定端口映射,格式为:主机(宿主)端口:容器端口
更多参数可以通过docker -help查看

(4) 一些其他常用的docker指令

# 列出所有镜像 
docker images
# 列出容器(运行中的)
docker ps
# 列出所有的容器(包括未运行的)
docker ps -a 
# 运行/停止容器
docker start/stop [CONTAINER ID]
# 删除容器
docker rm [CONTAINER ID]
# 删除镜像
docker rmi [IMAGE ID]

4. 如何为使用者提供服务

如果是公有开源的API服务,可以将镜像 push 到 docker cloud 上实现共享,使用者只要拉取你的镜像就可以在想要部署的服务器上运行服务;
但对于内部其实有更简单的方式,将整个项目文件上传到gitlab或其他类似平台,需要使用服务的人只需要通过拉取代码->创建docker镜像->启动容器运行docker镜像,就可以将服务灵活地部署到想要部署的服务器上;
别忘了写好README文档,主要将启动容器运行docker镜像的命令和API应用文档包含在内就好。

猜你喜欢

转载自blog.csdn.net/MarsherS/article/details/125630216