记录Python应用离线部署的两种方式

Published: 2019-07-03

Tags: Python

本文总阅读量

这两天写了几个基于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应用的优势

  1. 不会影响物理机环境

  2. 把镜像做好后有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

简要说明:

  1. docx-api.pex 是最终生成的可执行文件
  2. --python-shebang 参数指定 Python 解释器,这个需要目标机器也有,通用性来讲,py2大多数系统都会内置,py3则不是,所以此处指定的python
  3. flask,bjoern,python-docx为应用依赖
  4. 最后的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应用的优势:

  1. 在没有Docker环境的服务器上离线部署Python应用,简单方便
  2. 体积相比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参数包含当前文件夹下文件,会导致越打包越大...