Docker部署Flask应用
from flask import Flask
app = Flask(__name__)@app.route('/')
def hello_world():return 'Hello, World!'
以上代码是一个简单的Flask应用,但是在商业应用中,往往这不是最好的代码
在商业化项目中,都会降代码进行解耦,达到最大代码复用率,例如代码中的app
变量,那么如何搭建大型项目结构呢?可参照以下步骤
- Flask官方解决方案:
Flask官网的解决方式将Flask应用打包进一个模块包中,然后通过setuptools
的setup
函数启动,因为Python是不希望直接运行一个模块包的
例如:扫描二维码、条码项目
项目结构
application_init_.py
注意:这里必须引入使用了app
子文件
from flask import Flask# 定义app
app = Flask(__name__)# 引入子模块
import application.scancode
application\scancode.py
from flask import requestimport cv2
import base64
import numpy as np# 引入模块包中的app
from application import app# 扫描二维码
@app.route('/scancode/scanQrcode', methods=['POST'])
def scan_qrcode():base64_str = request.json.get('image')nparr = np.frombuffer(base64.b64decode(base64_str), np.uint8)# 读取图像image = cv2.imdecode(nparr, cv2.IMREAD_COLOR)code_detector = cv2.QRCodeDetector()decodes = code_detector.detectAndDecodeMulti(image)return {'data': decodes[1], "points": decodes[2].tolist()}# 扫描条形码
@app.route('/scancode/scanBarcode', methods=['POST'])
def scan_barcode():base64_str = request.json.get('image')nparr = np.frombuffer(base64.b64decode(base64_str), np.uint8)# 读取图像image = cv2.imdecode(nparr, cv2.IMREAD_COLOR)code_detector = cv2.barcode.BarcodeDetector()decodes = code_detector.detectAndDecodeMulti(image)return {'data': decodes[1], "points": decodes[2].tolist()}
setup.py
from setuptools import setup, find_packagessetup(name='application',version='1.0.0',setuptools='xx',packages=find_packages(),include_package_data=True,install_requires=['flask==3.1.1','opencv-python-headless==4.11.0.86'],
)
服务运行启动命令
# 这里的yourapplication使用项目结构中的目录名称,也就是__init__.py所在的目录
export FLASK_APP=application
pip install -e .
flask run
构建 Docker
Dockerfile
FROM python:3.9-slimWORKDIR /appCOPY . /appRUN python -m venv venv
RUN . venv/bin/activate
RUN pip install --no-cache-dir -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/EXPOSE 5000
构建镜像
# 获取版本号
version=$(cat setup.py | grep version | head -n 1 | awk -F '=' '{ print $2 }' | tr -d "[',]")docker rmi -f ${image_name}:$version
docker rmi -f ${image_name}:latest# 构建镜像
docker build -t ${image_name}:$version -t ${image_name}:latest .# 推送镜像
docker push ${image_name}:$version
docker push ${image_name}:latest
运行镜像
# 最后一定要指定主机IP为0.0.0.0,不然外部无法访问到容器内部的服务,如果像定义端口还可以用-p参数指定端口号,更多信息可运行flask run --help查看
docker run -d --name service - ${image_name}:latest /bin/sh -c 'export FLASK_APP=application && pip install -e . && flask run -h 0.0.0.0'