使用Conda Pack打包Python独立运行时环境
版本说明:
python=2.7
Conda 的Pack工具,可以说是让我发现了新大陆。之前有个项目使用它解决了一个棘手的问题,一直没有整理相关笔记,时间长了容易淡忘,恰好有同事问我如何实现的,这里就重新整理一下。
1 棘手问题描述
简单描述一下项目中遇到的这个棘手问题:
这个项目是一个Python2.7开发的Flask服务,它里面有不少依赖需要使用pip安装,并且在网络不好的情况下容易下载失败。要求是能够让用户能够快速部署,几乎不做复杂的操作,就能够运行我们的项目,甚至是目标主机没有联网的情况下,都能够直接运行。另外是,不考虑目标主机的Linux操作系统,不管是Ubuntu还是CentOS只要是Linux,就能够保证正常运行。另外,目前大多数系统都安装了Python3的环境,我们使用的Python2环境不能够影响到已有的环境。
当时想到了一些解决方法:
- 编写部署脚本,自动安装依赖。这个方法虽然能能够进行快速部署,但是安装依赖,需要考虑网络,不符合需求。
- 使用Pyinstaller等一些工具,可以打包成可执行文件。当时觉得这个方法可行,符合需求,但是由于我们这个Flask服务,里面依赖比较多,而且比较庞大。导致使用PyInstaller打包的时候,出现各种问题,经过几天的尝试,最终我还是放弃了,因为总是出现一些莫名其妙的问题,网上一些教程都是Hello World级别的,无法参考。也可能是个人能力问题,不过我还是放弃了。
2 使用Conda Pack解决问题
下面来讲一下,如何使用Conda Pack解决问题。思路相对来说比较简单,而且是容错率较高,不会出现莫名其妙的问题。思路是这样的:
- 首先使用Conda创建一个Python虚拟环境
- 激活创建的虚拟环境
- 在虚拟环境中安装项目运行时的依赖
- 使用Pack打包运行环境
- 将运行环境与项目源码一块发布
Pack打包的运行环境与项目源码一块拷贝的目标主机,解压后,激活运行环境,就可以直接运行项目了。
3 Conda Pack使用
从0到1讲一下如何使用Conda Pack打包一个Flask项目运行环境。
3.1 准备环境
准备一台centos机器,配置随意,可以访问互联网。
3.1.1 安装miniconda
Miniconda是conda的免费最小安装程序。它是Anaconda的小型引导程序版本,仅包含conda,Python,它们依赖的软件包以及少量其他有用的软件包,包括pip,zlib和其他一些软件包。官网地址:https://docs.conda.io/en/latest/miniconda.html
找到对应版本,进行下载。这里选择的是Linux的Python2.7的版本。
curl -k -o Miniconda2-latest-Linux-x86_64.sh https://repo.anaconda.com/miniconda/Miniconda2-latest-Linux-x86_64.sh
执行下载的脚本进行安装
sh Miniconda2-latest-Linux-x86_64.sh
根据提示按回车和输入yes即可。
安装完成后重启或者source ~/.bashrc,重新加载环境变量。查看conda版本
(base) [root@172 ~]# conda -V
conda 4.8.3
3.1.2 使用conda创建Python环境
使用conda命令创建一个名字为2.7版本号为2.7的python环境。
conda create -n 2.7 python=2.7
激活环境
conda activate 2.7
这时查看python版本号:
(2.7) [root@localhost ~]# python -V
Python 2.7.18 :: Anaconda, Inc
3.2 创建一个简单的Flask项目
这里就不从头开始创建项目了,我把已经创建好的项目,发布到Git上了,直接克隆下来即可。git地址:https://github.com/shirukai/flask-with-runtime-env.git
git clone https://github.com/shirukai/flask-with-runtime-env.git
进入项目
cd flask-with-runtime-env
安装项目依赖
pip install --no-cache-dir -r requirements.txt -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
测试启动项目
python application/main.py
3.3 打包运行环境
这里就要用到主角了:Conda Pack。官网地址:https://conda.github.io/conda-pack/。
官网文档安装Conda Pack的方法有三种,conda安装、pip包安装、pip源码安装。这里使用conda命令安装:
conda install -c conda-forge conda-pack
使用起来,也相对简单
# 该命令会将指定的名为my_env_name运行环境打包成my_env_name.tar.gz
conda pack -n my_env_name
我们也可以通过-o参数指定打包之后的名称
conda pack -n my_env_name -o out_name.tar.gz
将我们上面的2.7的环境打包
conda pack -n 2.7 -o 2.7.tar.gz
会在当前目录生成2.7.tar.gz。
创建一个名为2.7的目录
mkdir 2.7
将2.7.tar.gz解压到2.7目录下
tar -zxvf 2.7.tar.gz -C 2.7
执行如下命令激活环境
source 2.7/bin/activate
查看版本号
(2.7) [root@localhost flask-with-runtime-env]# python -V
Python 2.7.18 :: Anaconda, Inc.
将解压后的2.7文件夹重新打包成2.7.tar.bz2,用于我们flask程序的运行环境
tar -zcvf 2.7.tar.bz2 2.7/
移动到我们项目的env目录下
mv 2.7.tar.bz2 resources/env/
3.4 打包项目并测试
将运行环境放到env下之后,我们可以直接执行build.sh进行打包。
sh build.sh
执行完成后,查看target目录:
[root@localhost flask-with-runtime-env]# ls target/
flask-with-runtime-1.0.0.tar.gz
这个压缩包就是我们最终打包的程序,它里面带有独立的运行环境。只需要将它复制到要部署的机器上,解压,然后执行install脚本即可。
将压缩包复制到/opt/目录下
cp target/flask-with-runtime-1.0.0.tar.gz /opt/
去/opt目录下解压
[root@localhost flask-with-runtime-env]# cd /opt/
[root@localhost opt]# tar -zxvf flask-with-runtime-1.0.0.tar.gz
flask-with-runtime-1.0.0/
flask-with-runtime-1.0.0/application/
flask-with-runtime-1.0.0/application/main.pyc
flask-with-runtime-1.0.0/bin/
flask-with-runtime-1.0.0/bin/start
flask-with-runtime-1.0.0/bin/stop
flask-with-runtime-1.0.0/env/
flask-with-runtime-1.0.0/env/2.7.tar.bz2
flask-with-runtime-1.0.0/scripts/
flask-with-runtime-1.0.0/scripts/flask.service.template
flask-with-runtime-1.0.0/scripts/install.sh
进入flask-with-runtime-1.0.0目录,执行安装脚本
cd flask-with-runtime-1.0.0
[root@localhost flask-with-runtime-1.0.0]# sh scripts/install.sh
Created symlink from /etc/systemd/system/multi-user.target.wants/flask-application.service to /usr/lib/systemd/system/flask-application.service.
Installed successfully.
Please run command 'systemctl status flask-application' for more information about service.
查看运行状态
systemctl status flask-application
访问目标主机:5000