如何将Python 3.8设置为Docker的默认版本

12

我正在尝试更新一个现有的Dockerfile,将其从python3.5切换到python3.8,以前它会创建python3.5pip3的符号链接,如下所示:

RUN ln -s /usr/bin/pip3 /usr/bin/pip
RUN ln -s /usr/bin/python3 /usr/bin/python

我已经更新了Dockerfile,以从deadsnakes:ppa安装python3.8

apt-get install python3-pip python3.8-dev python3.8-distutils python3.8-venv
如果我删除python3-pip,它会抱怨gcc。
C编译器或Python头文件未安装在此系统上。尝试运行:sudo apt-get install gcc python3-dev
拥有这些安装后,我正在尝试更新现有的符号链接创建,类似于这样:
RUN ln -s /usr/bin/pip3 /usr/local/lib/python3.8/dist-packages/pip
RUN ln -s /usr/bin/pip /usr/local/lib/python3.8/dist-packages/pip
RUN ln -s /usr/bin/python3.8 /usr/bin/python3

构建过程失败并显示:

ln: failed to create symbolic link '/usr/bin/python3': File exists

我认为这是因为 python3 是指向 python3.6 的符号链接。

如果尝试使用 RUN ln -s /usr/bin/python3.8 /usr/bin/python,不会报错,镜像将成功构建,但稍后在安装要求时会失败(我们使用 Makefile 目标在容器内使用 pippip-sync 安装依赖项):

ERROR: Cannot uninstall 'python-apt'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.

我认为这是因为 python-apt 作为默认的 python3.6 安装的一部分被安装,而 python3.8 pip 无法卸载它。

PS:我的 Dockerfile 镜像基于 Ubuntu 18.04,默认情况下带有 python3.6

如何正确地将 Dockerfile/镜像从 python3.5 切换到 python3.8?这样我就可以直接使用 pip 并将其指向 python3.8pip

4个回答

18
以这种方式替换系统Python通常不是一个好主意(因为它可能会破坏依赖于这些可执行文件的操作系统级程序)--我在我制作的视频"Why not global pip / virtualenv?"中简要介绍了一下。
更好的方法是创建一个前缀并将其放在PATH之前(这允许系统可执行文件继续工作,但裸露的python / python3 /等将使用您的其他可执行文件)
在您使用deadsnakes的情况下,像这样做应该可以:
FROM ubuntu:bionic

RUN : \
    && apt-get update \
    && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
        software-properties-common \
    && add-apt-repository -y ppa:deadsnakes \
    && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
        python3.8-venv \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/* \
    && :

RUN python3.8 -m venv /venv
ENV PATH=/venv/bin:$PATH

ENV 行是关键,它将 virtualenv 放在路径的开头。

$ docker build -t test . 
...
$ docker run --rm -ti test bash -c 'which python && python --version && which pip && pip --version'
/venv/bin/python
Python 3.8.5
/venv/bin/pip
pip 20.1.1 from /venv/lib/python3.8/site-packages/pip (python 3.8)

免责声明:本人是deadsnakes的维护者。

1
感谢@Anthony做出的贡献,最初,我正在寻找一个不涉及virtualenv但安装了python3.8的解决方案,以便进行对系统级别安装的包的调试,但它并不喜欢...... 长话短说,将virtualenv纳入其中是最好的选择... 再次感谢! - Aarif
谢谢,这个方案可行。但是我可以把所有步骤放在一个RUN命令下吗? 如果我需要安装python3-venv、设置环境变量,然后运行pip install ...,我可以将它们都链在一个RUN命令下吗?我经常看到Dockerfiles中有一个巨大的RUN命令,可能是为了拥有小的层。RUN命令可以使用&&链接,但是在中间插入一个ENV命令有点棘手。也许我可以这样操作: apt-get install -y python3.8-venv && python3.8 -m venv /venv && PATH=/venv/bin:$PATH && pip install stuff 然后再用ENV PATH=/venv/bin:$PATH来使其在Docker中永久生效。你认为怎么样? - balazon

5
为什么不只是从ubuntu:18.04构建一个新的镜像,带上你需要的配置呢? 就像这样:
FROM ubuntu:18.04
RUN apt update && apt install software-properties-common -y
RUN add-apt-repository ppa:deadsnakes/ppa && install python3.8 -y
RUN ln -s /usr/bin/pip3 /usr/bin/pip && \
    ln -s /usr/bin/python3.8 /usr/bin/python

我实际上正在执行所有这些步骤,我跳过了添加 deadsnakes:ppa 的那些行,以使问题简短,让我尝试一下。 - Aarif
它成功地构建了镜像,但正如我所说,稍后涉及到使用Makefile目标在容器内使用pippip-sync安装依赖项的步骤失败,错误信息是“无法卸载'python-apt'”。 - Aarif
1
请不要单独运行 apt update,这会创建一个新层,存储在缓存中,可能会导致安装软件包时找不到。 - Maxime Chéramy

1
您可以安装和启用您的Python版本。
# Python 3.8 and pip3
RUN apt-get update
RUN apt-get install -y software-properties-common
RUN add-apt-repository ppa:deadsnakes/ppa -y
RUN apt-get install -y python3.8
RUN ln -s /usr/bin/python3.8 /usr/bin/python
RUN apt-get install -y python3-pip

当我尝试这个版本时,它要求我提供地理区域的输入。有没有办法绕过它? - Nikita Belooussov

0
有时候,修改操作系统(比如获取新的Ubuntu干净操作系统)并不可取,因为当前的操作系统过于复杂。例如,我的基础操作系统是从ufoym/deepo:all-cu101派生而来。
因此,为了将现有的Python(3.6)修改为Python 3.8,我添加了这两行代码:
RUN apt-get update -qq   && apt-get install -y -qq python3.8

RUN rm /usr/bin/python && rm /usr/bin/python3 && ln -s /usr/bin/python3.8 /usr/bin/python &&  ln -s /usr/bin/python3.8 /usr/bin/python3 \
    && rm /usr/local/bin/python && rm /usr/local/bin/python3 && ln -s /usr/bin/python3.8 /usr/local/bin/python &&  ln -s /usr/bin/python3.8 /usr/local/bin/python3 \
    && apt-get install -y python3-pip python-dev python3.8-dev && python3 -m pip install pip --upgrade

第一步是安装Python3.8; 第二步是修改python和python3的软链接,使其指向Python3.8。 之后,安装python3-pip,并更新它以确保pip使用当前的Python 3.8环境。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接