您如何使用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有关。所以我的问题:
docker build
在第一种情况下失败?如果我们只是在bash中运行这些命令,那就不会有任何错误。docker build
在第二种情况下成功?它与docker中的分层概念有什么关系?Dockerfile1
中指定点子版本(即pip install --upgrade pip=0.9.3
)也解决了这个问题?更新(2018年5月6日):
我已经弄明白了这个问题。这里发生的事情如下:
apt-get -y install python-pip
安装旧版本的pip,其shim脚本直接导入pip
的主要内容。
pip install --upgrade pip
安装pip 10.0.1
并将main
移至内部目录_internal
。它将其垫片脚本添加到PATH
。
pip
失败,因为它仍调用旧的填充脚本,因为它的路径已缓存。在中间运行hash -d pip
可以解决问题。显然,将安装和更新拆分为两个RUN
部分的效果与hash -d pip
相似。解决方法(Andriy Maletsky也建议)是1)pin pip
更新到9.0.3,或者2)首先从源安装(最新)pip,或者3)在中间使用hash -r
,或者4)使用另一个RUN命令以便稍后使用pip。
答案 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
进行此操作)。