Как бы вы объяснили 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
связана с этой заявленной проблемой . Итак, мои вопросы:
- Почему
docker build
терпит неудачу в первом случае? Если мы просто запустим эту команду в bash, ошибки не будет.
- Почему
docker build
удается во втором случае? Как это связано с концепцией расслоения в докере?
- Почему указание версии пипса в
Dockerfile1
(т. Е. pip install --upgrade pip=0.9.3
) также решает проблему?
Обновление (6 мая 2018 г.):
Я понял проблему. Что происходит здесь, как показано ниже:
apt-get -y install python-pip
устанавливает старую версию pip, чей скрипт shim напрямую импортирует pip
main.
pip install --upgrade pip
устанавливает pip 10.0.1
и перемещает main
во внутренний каталог _internal
. Он добавляет свой скрипт-шим к PATH
.
- Вызов
pip
завершается неудачно, так как он все еще вызывает старый скрипт shim, поскольку его путь кешируется. Выполнение промежуточного hash -d pip
устраняет проблему.
Таким образом, разделение установки и обновления на две секции RUN
имеет эффект, аналогичный hash -d pip
. Обходные пути (также предложенные Андреем Малецким): 1) pin pip
обновление до 9.0.3 или 2) установка (последний) pip из источника, во-первых, или 3) использование hash -r
между ними, или 4) использование другая команда RUN для последующего использования pip.