最近需要一个Python3.7的镜像,本来想直接用发行商的rpm直接安装,但由于要基于centos, 找了一下只有FreeBSD/Ubuntu有提供,没办法只要自己从源代码来编译。本来想着也是挺简易的,但过程却比较痛苦,折腾了好久,在这里整理一下。
其实总结下来,都是日志惹的祸,有些关键的日志在make的过程被刷了导致没有发现问题。我的步骤是这样的:
官方安装指南
./configure --prefix=/apps/svr/Python-3.7.6
make && make install
一切都很顺序,python3可以跑起来,但使用pip3 install包时却报错:
WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
Collecting threadpool
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by ‘S SLError(“Can’t connect to HTTPS URL because the SSL module is not available.”)’: /simple/threadpool/
WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by ‘S SLError(“Can’t connect to HTTPS URL because the SSL module is not available.”)’: /simple/threadpool/
WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by ‘S SLError(“Can’t connect to HTTPS URL because the SSL module is not available.”)’: /simple/threadpool/
ERROR: Could not find a version that satisfies the requirement threadpool (from versions: none)
ERROR: No matching distribution found for threadpool
搜索了一下,进去python3 shell尝试import ssl确实找不到ssl模块。
然后我就怀疑基础镜像内是不是没有装openssl,但却是有安装,而且用python2也是可以导致ssl模块
# rpm -qi openssl
Name : openssl
Epoch : 1
Version : 1.0.1e
Release : 51.el7_2.4
Architecture: x86_64
Install Date: Tue 05 Sep 2017 01:59:20 PM CST
Group : System Environment/Libraries
Size : 1611119
License : OpenSSL
Signature : RSA/SHA256, Wed 02 Mar 2016 12:03:36 AM CST, Key ID 24c6a8a7f4a80eb5
Source RPM : openssl-1.0.1e-51.el7_2.4.src.rpm
Build Date : Tue 01 Mar 2016 11:11:50 PM CST
Build Host : worker1.bsys.centos.org
Relocations : (not relocatable)
Packager : CentOS BuildSystem <http://bugs.centos.org>
Vendor : CentOS
URL : http://www.openssl.org/
Summary : Utilities from the general purpose cryptography library with TLS implementation
Description :
The OpenSSL toolkit provides support for secure communications between
machines. OpenSSL includes a certificate management tool and shared
libraries which provide various cryptographic algorithms and
protocols.
于是就Google了一下,有人说是在configure的时候要加ssl选项,但试了下面两个选项都没有解决。
./configure --with-ssl
./configure --with-ssl-default-suites
既然指定了要ssl模块的支持,configure的时候找不到模块就要有错误信息吧?因为日志太多,只好保存在文件中看看有没有一些ssl相关的错误日志,发现了下面的错误:
Failed to build these modules:
_ctypes
Could not build the ssl module!
Python requires an OpenSSL 1.0.2 or 1.1 compatible libssl with X509_VERIFY_PARAM_set1_host().
LibreSSL 2.6.4 and earlier do not provide the necessary APIs, https://github.com/libressl-portable/portable/issues/381
好吧,害死我的脑细胞,有错就就不能停一下么?3.7必须是1.0.2以上的ssl版本才可以,我现在的openssl版本是1.0.1,没办法得再装openssl,为了不覆盖现在的版本:
cd /tmp && tar -xvf openssl-1.1.1f.tar.gz && \
cd /tmp/openssl-1.1.1f && ./config --prefix=/usr/local/openssl && make && make install && \
rm -rf /tmp/openssl-1.1.1f /tmp/openssl-1.1.1f.tar.gz && \
ln -s /usr/local/openssl/include/openssl /usr/include/openssl && \
ln -s /usr/local/openssl/lib/libssl.so.1.1 /usr/local/lib64/libssl.so && \
rm -rf /usr/bin/openssl && \
ln -s /usr/local/openssl/bin/openssl /usr/bin/openssl && \
echo "/usr/local/openssl/lib" >> /etc/ld.so.conf && \
ls -l /usr/local/openssl/lib && \
ldconfig -v && \
openssl version
openssl安装完毕后,在configure python3.7
./configure --with-openssl=/usr/local/openssl --prefix=/apps/svr/Python-3.7.6 && make install
终于搞定!!
完整的Dockerfile: Python3.7.6