这两天写了几个基于Python的接口,功能很简单,页面通过接口传过来数据,后端生成 docx 文档并提供下载,开发完成,到了部署的环节,离线部署,突然没了思路,了解并测试了一番,总结如下
(一)Docker 部署
镜像可以在这里获取:https://hub.docker.com/_/python
因为是从Dockerfile构建,那么需要编辑修改一些地址,以加快下载包的速度
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
将原下载Python代码的路径替换为国内FTP地址(我放到自己的FTP里了):
https://pan.yasking.org/python3.7.3/Python-3.7.3.tar.xz
https://pan.yasking.org/python3.7.3/Python-3.7.3.tar.xz.asc
另外获取pip的地址如果访问慢也可以修改一下
https://pan.yasking.org/python3.7.3/get-pip.py
构建 Python 镜像
docker build -t python:3.7.3 .
基础镜像构建完成,如果要运行自己的镜像,那么我会在这个镜像的基础上再构建一个应用镜像
FROM python:3.7.3
WORKDIR /opt/work
# Bundle APP files
COPY requirements.txt ./
COPY server.py ./
COPY somedir somedir/
RUN apk add --update \
libev-dev \
libpng-dev autoconf automake nasm libtool \
libxml2 libxslt libxml2-dev libxslt-dev \
&& rm -rf /var/cache/apk/*
RUN pip3 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
RUN pip3 install --no-cache-dir -r requirements.txt
CMD [ "python3", "./server.py" ]
再次构建自己的镜像
docker build -f Dockerfile-build -t mypy .
这个镜像又新添加了一些软件包,以及程序相关依赖,文件。工作目录是容器内的 /opt/work 目录
启动应用前把 server.py 复制到宿主机的 /opt/work/project01 目录
docker run -it --rm --name container_name -p 8750:8750 -v /opt/work/project01:/opt/work mypy
启动容器后就可以看到应用启动输出了,如果没问题,可以结束掉,并且把 -it --rm
替换为 -d
后台启动
使用Docker部署Python应用的优势
-
不会影响物理机环境
-
把镜像做好后有Docker的环境就能运行
让人不舒服的地方是镜像比较大,原始镜像构建出来就有300M,我又包裹了一层镜像后,导出的镜像压缩后也有200M,很小的服务,这个体积不能让人满意,可以进一步减少层来减小体积,不过感觉优化空间不大
(二)Pex 打包
之前使用过Pyinstaller打包,但是不同系统的glibc版本不一致会导致运行失败
搜索过程了解到了另一种打包方式:Pex
使用起来也很简单
pex -o docx-api.pex --python-shebang='/usr/bin/env python' -D . flask bjoern python-docx -e server
简要说明:
- docx-api.pex 是最终生成的可执行文件
- --python-shebang 参数指定 Python 解释器,这个需要目标机器也有,通用性来讲,py2大多数系统都会内置,py3则不是,所以此处指定的python
- flask,bjoern,python-docx为应用依赖
- 最后的server,是指我的py程序,名为server.py
打包后的 docx-api.pex 大小 6.8M
[dongdong@fedora29 docx-api]$ du -sh docx-api.pex
6.8M docx-api.pex
使用Pex部署Python应用的优势:
- 在没有Docker环境的服务器上离线部署Python应用,简单方便
- 体积相比Docker镜像大幅减小
使用Pex还是需要自己解决一些问题,比如我使用了 bjoern 模块,它用到了 libev 事件库,然而 Centos 7 默认没有这个,所以我手动下载了 libev-4.15-7.el7.x86_64.rpm, 可以在这个网站搜索 rpm 包下载:https://centos.pkgs.org/
安装 rpm 包:
yum localinstall libev-4.15-7.el7.x86_64.rpm
将 docx-api.pex 复制到目标机器加权限运行即可
最后记得,每次运行构建pex脚本的时候记得先删除之前的pex文件,不然-D
参数包含当前文件夹下文件,会导致越打包越大...