如果在单个RUN部分

时间:2018-05-05 01:32:03

标签: python docker pip dockerfile

您如何使用docker build解释Dockerfile1失败,并使用Dockerfile2取得成功(见下文)。

1)

// Dockerfile1

FROM ubuntu:16.04

RUN apt-get -y update && \
    apt-get -y install python-pip python-dev build-essential && \
    pip install --upgrade pip && \
    pip install --upgrade virtualenv

docker build .失败并出现以下错误

Collecting pip
Downloading 
https://files.pythonhosted.org/packages/0f/74/ecd13431bcc456ed390b44c8a6e917c1820365cbebcb6a8974d1cd045ab4/pip-10.0.1-py2.py3-none-any.whl (1.3MB)
Installing collected packages: pip
Found existing installation: pip 8.1.1
Not uninstalling pip at /usr/lib/python2.7/dist-packages, outside 
environment /usr
Successfully installed pip-10.0.1
Traceback (most recent call last):
File "/usr/bin/pip", line 9, in <module>
   from pip import main
ImportError: cannot import name main
The command '/bin/sh -c apt-get -y update &&     apt-get -y install 
python-pip python-dev build-essential &&     pip install --upgrade pip &&     pip install --upgrade virtualenv &&     virtualenv /venv' returned a non-zero code: 1

但是,如果我们将其分成两个RUN,它就会成功。

2)

// Dockerfile2

FROM ubuntu:16.04

RUN apt-get -y update && \
    apt-get -y install python-pip python-dev build-essential && \
    pip install --upgrade pip

RUN pip install --upgrade virtualenv

pip的安装失败与此reported issue有关。所以我的问题:

  1. 为什么docker build在第一种情况下失败?如果我们只是在bash中运行这些命令,那就不会有任何错误。
  2. 为什么docker build在第二种情况下成功?它与docker中的分层概念有什么关系?
  3. 为什么在Dockerfile1中指定点子版本(即pip install --upgrade pip=0.9.3)也解决了这个问题?
  4.   

    更新(2018年5月6日):

    我已经弄明白了这个问题。这里发生的事情如下:

    1. apt-get -y install python-pip安装旧版本的pip,其shim脚本直接导入pip的主要内容。

    2. pip install --upgrade pip安装pip 10.0.1并将main移至内部目录_internal。它将其垫片脚本添加到PATH

    3. 调用pip失败,因为它仍调用旧的填充脚本,因为它的路径已缓存。在中间运行hash -d pip可以解决问题。
    4. 显然,将安装和更新拆分为两个RUN部分的效果与hash -d pip相似。解决方法(Andriy Maletsky也建议)是1)pin pip更新到9.0.3,或者2)首先从源安装(最新)pip,或者3)在中间使用hash -r,或者4)使用另一个RUN命令以便稍后使用pip。

1 个答案:

答案 0 :(得分:2)

问题是,{p}从第9版更新到第10版时pip可执行文件(/usr/bin/pip)中断了。

可能的解决方案:
1.请勿更新和使用pip v9
2.不要使用apt-get来安装pip。 Download it manually

  

为什么docker build在第一种情况下失败?如果我们只是在bash中运行这些命令,那就不会有任何错误。

不,会有错误。我在docker run --rm -it ubuntu:16.04 bash内运行了这些命令并得到了它。

  

为什么docker build在第二种情况下成功?它与docker中的分层概念有什么关系?

我相信你在第二次RUN的某个地方犯了一个错误而且它正在消除一个错误(在那个你没有提供的地方)。例如,这将起作用(因为;使用而不是&&并且在执行错误命令后执行不会中断:

RUN pip install --upgrade virtualenv && \
virtualenv /venv; source /venv/bin/activate
  

为什么在Dockerfile1中指定pip版本(即pip install --upgrade pip = 0.9.3)也解决了这个问题?

因为这个pip bug出现在版本10中。

P.S。您不应通过apt-get更新或手动更改添加到系统中的文件(通过pip install --upgrade pip进行此操作)。