The value of knowledge lies not in possession, but in share.

0%

一个算法Web API项目的Docker部署示例

本文为上篇文章《初用Docker总结》中所提到的,对自己的一个算法项目的进行Docker镜像制作的一个大致的流程。也算是填了上文中挖的坑,谨做记录,将来遗忘流程时借以查阅。

Pecan 介绍

Pecan 的创建是为了填补 Python Web 框架世界中的空白:一个非常轻巧的框架,它提供了对象分派样式路由(object-dispatch style routing)。Pecan 并非旨在成为“全栈”框架,因此不提供对会话(sessions)或数据库之类的现成支持。相反地 Pecan 专注于 HTTP 本身。

Pecan官网:http://www.pecanpy.org/

Pecan 封装算法

  1. 安装Pecan

    1
    pip install pecan
  2. 创建Pecan项目

    1
    pecan create test_project
  3. 安装Pecan默认库

    1
    python setup.py develop

    python setup.py develop:安装某个库或包时,这个包需要你不断修改,这样你就不得不重新安装,这时就采用这种安装方法。
    python setup.py install:主要是安装典型第三方包,这种包比较稳定,不再需要你去编辑、修改或是调试。

    生成的目录结构如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    test_project/
    ├── config.py
    ├── MANIFEST.in
    ├── public #一些静态文件包括CSS,JS,images,为你的开发服务
    │ ├── css
    │ │ └── style.css
    │ └── images
    │ └── logo.png
    ├── setup.cfg
    ├── setup.py
    └── test_project #基于MVC模型生成的结构
    ├── app.py #决定应用是如何创造的,这个文件必须包含set_app()并返回WSGI应用对象,一般情况下就用原生的,除非不能满足你定制的应用。
    ├── controllers #控制层实现
    │ ├── __init__.py
    │ ├── __init__.pyc
    │ ├── root.py
    │ └── root.pyc
    ├── __init__.py
    ├── __init__.pyc
    ├── model #模型实现
    │ ├── __init__.py #在这里可以加入与database交互,定义表和ORM等
    │ └── __init__.pyc
    ├── templates #模板实现
    │ ├── error.html
    │ ├── index.html
    │ └── layout.html
    └── tests #单元测试
    ├── config.py
    ├── __init__.py
    ├── test_functional.py
    ├── test_units.py
    └── test_units.pyc
    8 directories, 23 files
  4. 封装算法

    一般我个人习惯将待封装的算法脚本放在controllers文件夹下。

    在同目录root.py脚本中封装自己的算法。

制作Python3.8 + OpenCV4.5.0 基础镜像

Dockerfile内容如下,并将从OpenCV官网下载的opencv-4.5.0.zip放在同目录下,此目录中不可有其他文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
FROM python:3.8
LABEL mantainer="Josip Janzic <josip@jjanzic.com>"

RUN apt-get update \
&& apt-get install -y \
build-essential \
cmake \
git \
wget \
unzip \
yasm \
pkg-config \
libswscale-dev \
libtbb2 \
libtbb-dev \
libjpeg-dev \
libpng-dev \
libtiff-dev \
libavformat-dev \
libpq-dev \
&& rm -rf /var/lib/apt/lists/*

RUN pip install numpy
ADD ./opencv-4.5.0.zip /
WORKDIR /
RUN unzip opencv-4.5.0.zip \
&& mkdir /opencv-4.5.0/cmake_binary \
&& cd /opencv-4.5.0/cmake_binary \
&& cmake -DBUILD_TIFF=ON \
-DBUILD_opencv_java=OFF \
-DWITH_CUDA=OFF \
-DWITH_OPENGL=ON \
-DWITH_OPENCL=ON \
-DWITH_IPP=ON \
-DWITH_TBB=ON \
-DWITH_EIGEN=ON \
-DWITH_V4L=ON \
-DBUILD_TESTS=OFF \
-DBUILD_PERF_TESTS=OFF \
-DCMAKE_BUILD_TYPE=RELEASE \
-DCMAKE_INSTALL_PREFIX=$(python3.8 -c "import sys; print(sys.prefix)") \
-DPYTHON_EXECUTABLE=$(which python3.8) \
-DPYTHON_INCLUDE_DIR=$(python3.8 -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())") \
-DPYTHON_PACKAGES_PATH=$(python3.8 -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())") \
.. \
&& make install \
&& rm /opencv-4.5.0.zip \
&& rm -r /opencv-4.5.0
RUN ln -s \
/usr/local/python/cv2/python-3.8/cv2.cpython-37m-x86_64-linux-gnu.so \
/usr/local/lib/python3.8/site-packages/cv2.so

构建Python3.8 + OpenCV4.5.0基础镜像

1
2
3
4
# 构建镜像
docker build -t wangcong/python38-opencv:v1.0.0 .
# 注意,最后有一个点,表示在本目录下进行构建
# 其中-t用来指定新镜像的用户信息、tag等。

基于 基础镜像 制作 项目依赖镜像

可以参考《初用Docker总结》一文中 通过已有镜像来新建自有镜像,来基于Python3.8 + OpenCV4.5.0基础镜像 制作 项目依赖镜像

制作 算法 Web API 镜像

通过Dockerfile,对算法项目进行镜像打包。

Dockerfile内容如下,并将算法项目放在同目录下,此目录中不可有其他文件。requirements.txt位于算法项目 目录中。

1
2
3
4
5
6
7
FROM wangcong/python38-opencv:v1.0.0
RUN mkdir /a_web_api_example
ADD ./a_web_api_example /a_web_api_example/
WORKDIR /a_web_api_example
#RUN pip install -r requirements.txt
RUN python setup.py develop
ENTRYPOINT ["pecan", "serve", "config.py"]

基于项目依赖镜像 创建 算法Web API镜像

1
2
3
4
# 构建镜像
docker build -t wangcong/a_web_api_example:v1.0.0 .
# 注意,最后有一个点,表示在本目录下进行构建
# 其中-t用来指定新镜像的用户信息、tag等。

🍭支持一根棒棒糖吧!