当下我需要一个python3.8的镜像,这时候,首先从官网上下载一个python3.8的tgz包。地址如下:Index of /ftp/python/3.8.10/Python-3.8.10.tgz
首先,可以先构建一个dockerfile去生成python3.8的镜像。但是这个过程需要安装一些依赖,有可能出现很多报错。一旦报错,docker build . -t xxx(镜像名) 就会执行失败,但是,镜像依旧会被创出来,只是显示为None。这时记得要删除这些无用的镜像,平常删镜像使用命令:docker rmi xxx(镜像id) 即可,但是这种构建失败的镜像使用该方法会显示无法删除,所以需要使用命令:docker rmi -f xxx(镜像id) 即可。
本次我没有使用自己构建dockerfile的方式来生成需要的镜像,而是采用了借鸡生蛋的方式生成所需镜像。这里有一篇帖子是使用dockerfile生成python镜像的,可以看一下:
https://www.jb51.net/article/177259.htm
首先,需要先下载一个python镜像,当然肯定没有现成的python3.8版本的,但是可以下载python3.7的,这个刚刚有现成的。http://build-docker-main.artifactory.eng.vmware.com/buildsystem_py37:v1.0
下载完成后,docker images 查看一下:
然后运行这个镜像: docker run xxx(镜像id) sleep 10000
之后就会生成一个容器了:docker ps
然后,就开始对这个容器进行更改:
由于我们是要弄python3.8版本的镜像。因此,需要在这个容器里安装python3.8,同时最好把原来的python3.7删除(不删除也行,但是需要注意安装时在 ./configure --prefix=/xx/xx/xx指定安装目录),这里在删除时需要注意3个文件,由于python在安装时,会默认下载到 /usr/local/ 文件夹,下载时其会将可执行文件下载到 /usr/local/bin 目录,将库文件下载到 /usr/local/lib 目录,将配置文件下载到 /usr/local/include 目录,所以我们需要将这三个文件的内容全部清除。
然后使用命令: docker cp xxx(容器外文件) xxx(容器id):/xx/xx(容器内即将存放容器文件的位置)
eg: docker cp Python-3.8.10.tgz f1783d8c84e3:/home
将之前下载的tgz包,复制到容器内。
然后就可以进入容器:docker exec -it xx(容器id) /bin/bash
开始安装python3.8:
tar -zxvf Python-3.8.10.tgz
cd Python-3.8.10
./configure (默认会下载到 /usr/local/ , 此处也可指定路径,区别是,如果存在了其他的 python,这时相关文件都会出现在/usr/local/bin, /usr/local/include, 以及 /usr/local/lib里,会比较混乱,所以,如果指定了目录就会避免这种情况。例如:在此处添加参数 --prefix=/usr/local/python3.8,这时,所需的相关文件就会下载到 /usr/local/python3.8/bin, /usr/local/python3.8/lib, /usr/local/python3.8/include),但是这里也会有一个坑,如果安装python3.8的时候,没有直接安装到 /usr/local/ 下,而是多添加了一级目录,是从整体看,更加的集成,但是就不会在 /usr/local/lib 创建相应的python3.8,如图:
如果 /usr/local/ 下没有 python3.8 那么回头用python3.8创建虚拟环境的时候会报错的。如图:
所以,最好还是将python3.8放到 /usr/local/ 下,会比较方便,少一些后续莫名其妙的问题。当然个人猜想,如果在 /usr/local/lib 搞个软连接将,/usr/local/python3.8/lib 的 lib 连接到 /usr/local/lib 能不能规避无法创建虚拟环境的问题呢?这个没试,当时出现无法创建虚拟环境的问题后,选择重新安装python3.8到 /usr/local/ 下,确实就可以创建虚拟环境了。
make && make install
cd /usr/local/bin
ln -s pip3.8 /usr/bin/pip3.8
ln -s python3.8 /usr/bin/python3.8
至此容器里的python3就从python3.7变成了python3.8,完成了偷梁换柱。
然后,重新开一个terminal, 执行命令:docker commit xx(容器id) xx(镜像名)
就可以生成新的python3.8镜像了
docker images查看下:
注意,python3.8的安装过程有可能出一些坑,这里简单介绍一些:
错误提示1:
Python requires an OpenSSL 1.0.2 or 1.1 compatible libssl with X509_VERIFY_P
这是说:python3.7以上建议使用libssl代替openssl,故需通过源码编译安装libressl...
这个可以参考帖子:python3 openssl_python3解决ssl问题_weixin_39703551的博客-CSDN博客
基本可以解决问题,命令总结如下:
wget https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-3.0.2.tar.gz
tar -zxvf libressl-3.0.2.tar.gz
cd libressl-3.0.2/
./configure --prefix=/usr/local/libressl
make
sudo make install
sudo mv /usr/include/openssl /usr/include/openssl.bak
sudo mv /usr/bin/openssl /usr/bin/openssl.bak
sudo mv /usr/include/openssl /usr/include/openssl.bak
sudo ln -s /usr/local/libressl/bin/openssl /usr/bin/openssl
sudo ln -s /usr/local/libressl/include/openssl /usr/include/openssl
验证是否成功:
openssl version
接下来三步很重要,如果没有执行,那么安装好的python是无法使用ssl包的
export LDFLAGS="-L/usr/local/libressl/lib"
export CPPFLAGS="-I/usr/local/libressl/include"
export PKG_CONFIG_PATH="/usr/local/libressl/lib/pkgconfig"
然后需要重新编译安装python3.*
就是: cd python包
./configure
make
sudo make install 这一套
错误提示2:
zipimport.ZipImportError: can't decompress data; zlib not available
这个是说:zlib not available
意思是在编译安装 Python 3.* 时找不到 zlib 的开发链接库(头文件和链接库),导致无法编译安装而提示的错误。
这里可以参考帖子:zlib包的小载_m0_46900715的博客-CSDN博客
基本可以解决问题,命令总结如下:
wget http://www.zlib.net/zlib-1.2.12.tar.gz
tar -xvf zlib-1.2.12.tar.gz
cd zlib-1.2.12/
./configure
make
sudo make install
然后,还需要重新编译python3.*,也就是重新make ,sudo make install
只要不报错,就ok了