Добавление требований pip к образу docker во время выполнения

Я хочу иметь возможность добавить некоторые дополнительные требования к собственному образу create docker. Моя стратегия-создать образ из файла dockerfile с помощью команды CMD, которая выполнит команду "pip install-r", используя смонтированный том во время выполнения.

Это мой dockerfile:

FROM ubuntu:14.04

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

WORKDIR /root

CMD ["pip install -r /root/sourceCode/requirements.txt"]

имея этот dockerfile, я создаю изображение:

sudo docker build -t test .

и, наконец, я пытаюсь добавить новые требования, используя эту команду:

sudo docker run -v $(pwd)/sourceCode:/root/sourceCode -it test /bin/bash

моя локальная папка "sourceCode" имеет внутри допустимые требования.txt файл (содержит только одну строку со значением "gunicorn"). Когда я получаю приглашение, я вижу, что файл требований есть, но если я выполняю команду pip freeze, пакет gunicorn не указан.

почему требования.txt файл был прикреплен правильно, но команда pip работает неправильно?

3 ответов


TLDR

pip команда не выполняется, потому что вы говорите докеру запустить /bin/bash вместо.

docker run -v $(pwd)/sourceCode:/root/sourceCode -it test /bin/bash
                                                              ^
                                                             here

больше объяснений

по умолчанию ENTRYPOINT в контейнер /bin/sh -c. Вы не переопределяете это в Dockerfile, так что это остается. Значение по умолчанию CMD инструкция, вероятно, ничего. Вы переопределяете это в своем Dockerfile. При запуске (игнорируйте громкость для краткости)

docker run -it test

что фактически выполняются внутри контейнера

/bin/sh -c pip install -r /root/sourceCode/requirements.txt

довольно прямо вперед, похоже, что он будет работать pip при запуске контейнера.

теперь давайте посмотрим на команду, которую вы использовали для запуска контейнера (опять же, игнорируя Тома)

docker run -v -it test /bin/bash

то, что фактически выполняется внутри контейнера, является

/bin/sh -c /bin/bash

the CMD аргументы, указанные в файле Dockerfile, переопределяются COMMAND вы укажите в командной строке. Вспомните это docker run команда принимает эту форму

docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]

более дальнеишее чтение

  1. ответ имеет действительно до точки объяснение того, что CMD и ENTRYPOINT инструкции

    на ENTRYPOINT задает команду, которая всегда будет выполняться при запуске контейнера.

    на CMD указывает аргументы, которые будут переданы ENTRYPOINT.

  2. этой блоге о разнице между ENTRYPOINT и CMD инструкции, которые стоит читать.


вы можете изменить последнее утверждение, т. е. CMD ниже.

--укажите абсолютный путь расположения pip в приведенной ниже инструкции

CMD ["/usr/bin/pip", "install", "-r", "/root/sourceCode/requirements.txt"]

обновление: добавление дополнительного ответа на основе комментариев.

одна вещь, следует отметить, что если образ нужно с Дополнительные требования, которые должны часть изображения, а не во время выполнения.

используя под низкопробным изображением к тест:

docker pull colstrom/python:legacy

так, установка пакетов должна выполняться с помощью RUN команда Dockerfile.
И CMD следует использовать, какие приложения вы на самом деле хотели запустить как процесс внутри контейнера.

просто проверьте, имеет ли базовое изображение какие-либо пакеты pip, выполнив команду ниже и результаты ничего.

docker run --rm --name=testpy colstrom/python:legacy /usr/bin/pip freeze

вот простой пример, чтобы продемонстрировать же:

Dockerfile

FROM colstrom/python:legacy
COPY requirements.txt /requirements.txt
RUN ["/usr/bin/pip", "install", "-r", "/requirements.txt"]
CMD ["/usr/bin/pip", "freeze"]

требований.txt

selenium

создайте изображение с помощью пакетов pip надеюсь, вы знаете, чтобы разместить Dockerfile, требования.txt файл в новый каталог.

D:\dockers\py1>docker build -t pypiptest .
Sending build context to Docker daemon 3.072 kB
Step 1 : FROM colstrom/python:legacy
 ---> 640409fadf3d
Step 2 : COPY requirements.txt /requirements.txt
 ---> abbe03846376
Removing intermediate container c883642f06fb
Step 3 : RUN /usr/bin/pip install -r /requirements.txt
 ---> Running in 1987b5d47171
Collecting selenium (from -r /requirements.txt (line 1))
  Downloading selenium-3.0.1-py2.py3-none-any.whl (913kB)
Installing collected packages: selenium
Successfully installed selenium-3.0.1
 ---> f0bc90e6ac94
Removing intermediate container 1987b5d47171
Step 4 : CMD /usr/bin/pip freeze
 ---> Running in 6c3435177a37
 ---> dc1925a4f36d
Removing intermediate container 6c3435177a37
Successfully built dc1925a4f36d
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.

Теперь запустите изображения Если вы не передаете какую-либо внешнюю команду, контейнер принимает команду из CMD который просто показывает список pip пакеты. Здесь в это дело,selenium.

D:\dockers\py1>docker run -itd --name testreq pypiptest
039972151eedbe388b50b2b4cd16af37b94e6d70febbcb5897ee58ef545b1435

D:\dockers\py1>docker logs testreq
selenium==3.0.1

Итак, выше показано, что пакет успешно установлен.

надеюсь, это поможет.


используя концепции, которые @Rao и @ROMANARMY объяснили в своих ответах, я узнаю, наконец, способ сделать то, что я хотел: добавить дополнительные требования python к самостоятельно созданному образу докера.

мой новый Dockerfile выглядит следующим образом:

FROM ubuntu:14.04

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

WORKDIR /root

COPY install_req.sh .

CMD ["/bin/bash" , "install_req.sh"]

я добавил в качестве первой команды выполнение сценария оболочки, который имеет следующее содержимое:

#!/bin/bash
pip install -r /root/sourceCode/requirements.txt
pip freeze > /root/sourceCode/freeze.txt

и, наконец, я создаю и запускаю изображение с помощью следующих команд:

docker build --tag test .
docker run -itd --name container_test -v $(pwd)/sourceCode:/root/sourceCode test <- without any parameter at the end

как я объяснил на в начале поста у меня в локальной папке есть папка с именем sourceCode, которая содержит допустимые требования.txt файл только с одной строкой "gunicorn"

Итак, наконец, у меня есть возможность добавить некоторые дополнительные требования (пакет gunicorn в этом примере) к данному изображению докера.

после построения и запуска моего эксперимента, если я проверить логи (docker logs container_test) Я вижу что-то вроде этого:

Downloading gunicorn-19.6.0-py2.py3-none-any.whl (114kB)
    100% |################################| 122kB 1.1MB/s 
Installing collected packages: gunicorn

кроме того, контейнер создал замораживание.txt-файл внутри смонтированного Тома, содержащего все установленные пакеты pip, включая желаемый gunicorn:

chardet==2.0.1
colorama==0.2.5
gunicorn==19.6.0
html5lib==0.999
requests==2.2.1
six==1.5.2
urllib3==1.7.1

теперь у меня есть другие проблемы с разрешениями нового созданного файла, но это, вероятно, будет в новом сообщении.

спасибо!