Как избежать переустановки пакетов при создании образа Docker для проектов Python?


мой Dockerfile-это что-то вроде

FROM my/base

ADD . /srv
RUN pip install -r requirements.txt
RUN python setup.py install

ENTRYPOINT ["run_server"]

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

Я думаю cache пакеты, которые были установлены, чтобы переопределить my/base изображение с новыми изображениями, как это:

docker build -t new_image_1 .
docker tag new_image_1 my/base

так что в следующий раз, когда я построю с этим Dockerfile, у моего/base уже есть некоторые установленные пакеты.

но это решение имеет два проблемы:

  1. не всегда возможно переопределить базовое изображение
  2. базовое изображение становится все больше и больше, поскольку новые изображения накладываются на него

Итак, какое лучшее решение я могу использовать для решения этой проблемы?

EDIT##:

некоторая информация о докере на моей машине:

☁  test  docker version
Client version: 1.1.2
Client API version: 1.13
Go version (client): go1.2.1
Git commit (client): d84a070
Server version: 1.1.2
Server API version: 1.13
Go version (server): go1.2.1
Git commit (server): d84a070
☁  test  docker info
Containers: 0
Images: 56
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Dirs: 56
Execution Driver: native-0.2
Kernel Version: 3.13.0-29-generic
WARNING: No swap limit support
3 69

3 ответа:

попробуйте построить с помощью ниже Dockerfile.

FROM my/base

WORKDIR /srv
ADD ./requirements.txt /srv/requirements.txt
RUN pip install -r requirements.txt
ADD . /srv
RUN python setup.py install

ENTRYPOINT ["run_server"]

если есть какие-то изменения на .(ваш проект), docker skip pip install строка с помощью кэша.

настройки работать только pip install при сборке при редактировании требований.txt-файл.


я пишу просто .

$ tree
.
├── Dockerfile
├── requirements.txt
└── run.py   

0 directories, 3 file

# Dockerfile

FROM dockerfile/python
WORKDIR /srv
ADD ./requirements.txt /srv/requirements.txt
RUN pip install -r requirements.txt
ADD . /srv
CMD python /srv/run.py

# requirements.txt
pytest==2.3.4

# run.py
print("Hello, World")

ниже есть выход.

Step 1 : WORKDIR /srv
---> Running in 22d725d22e10
---> 55768a00fd94
Removing intermediate container 22d725d22e10
Step 2 : ADD ./requirements.txt /srv/requirements.txt
---> 968a7c3a4483
Removing intermediate container 5f4e01f290fd
Step 3 : RUN pip install -r requirements.txt
---> Running in 08188205e92b
Downloading/unpacking pytest==2.3.4 (from -r requirements.txt (line 1))
  Running setup.py (path:/tmp/pip_build_root/pytest/setup.py) egg_info for package pytest
....
Cleaning up...
---> bf5c154b87c9
Removing intermediate container 08188205e92b
Step 4 : ADD . /srv
---> 3002a3a67e72
Removing intermediate container 83defd1851d0
Step 5 : CMD python /srv/run.py
---> Running in 11e69b887341
---> 5c0e7e3726d6
Removing intermediate container 11e69b887341
Successfully built 5c0e7e3726d6

я обновляю только run.py и попытаться построить снова.

# run.py
print("Hello, Python")

ниже есть выход.

Sending build context to Docker daemon  5.12 kB
Sending build context to Docker daemon 
Step 0 : FROM dockerfile/python
---> f86d6993fc7b
Step 1 : WORKDIR /srv
---> Using cache
---> 55768a00fd94
Step 2 : ADD ./requirements.txt /srv/requirements.txt
---> Using cache
---> 968a7c3a4483
Step 3 : RUN pip install -r requirements.txt
---> Using cache
---> bf5c154b87c9
Step 4 : ADD . /srv
---> 9cc7508034d6
Removing intermediate container 0d7cf71eb05e
Step 5 : CMD python /srv/run.py
---> Running in f25c21135010
---> 4ffab7bc66c7
Removing intermediate container f25c21135010
Successfully built 4ffab7bc66c7

как вы можете видеть выше, docker использует кэш сборки. И я обновляю требования.на этот раз txt.

# requirements.txt

pytest==2.3.4
ipython

ниже есть выход.

Sending build context to Docker daemon  5.12 kB
Sending build context to Docker daemon 
Step 0 : FROM dockerfile/python
---> f86d6993fc7b
Step 1 : WORKDIR /srv
---> Using cache
---> 55768a00fd94
Step 2 : ADD ./requirements.txt /srv/requirements.txt
---> b6c19f0643b5
Removing intermediate container a4d9cb37dff0
Step 3 : RUN pip install -r requirements.txt
---> Running in 4b7a85a64c33
Downloading/unpacking pytest==2.3.4 (from -r requirements.txt (line 1))
  Running setup.py (path:/tmp/pip_build_root/pytest/setup.py) egg_info for package pytest

Downloading/unpacking ipython (from -r requirements.txt (line 2))
Downloading/unpacking py>=1.4.12 (from pytest==2.3.4->-r requirements.txt (line 1))
  Running setup.py (path:/tmp/pip_build_root/py/setup.py) egg_info for package py

Installing collected packages: pytest, ipython, py
  Running setup.py install for pytest

Installing py.test script to /usr/local/bin
Installing py.test-2.7 script to /usr/local/bin
  Running setup.py install for py

Successfully installed pytest ipython py
Cleaning up...
---> 23a1af3df8ed
Removing intermediate container 4b7a85a64c33
Step 4 : ADD . /srv
---> d8ae270eca35
Removing intermediate container 7f003ebc3179
Step 5 : CMD python /srv/run.py
---> Running in 510359cf9e12
---> e42fc9121a77
Removing intermediate container 510359cf9e12
Successfully built e42fc9121a77

и docker не использует кэш сборки. Если это не работает, проверьте версию docker.

Client version: 1.1.2
Client API version: 1.13
Go version (client): go1.2.1
Git commit (client): d84a070
Server version: 1.1.2
Server API version: 1.13
Go version (server): go1.2.1
Git commit (server): d84a070

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

запустите контейнер docker с привязкой каталога кэша pip вашего хоста, смонтированной в каталоге кэша pip вашего контейнера. docker run команда должна выглядеть так:

docker run -v $HOME/.cache/pip/:/root/.cache/pip image_1

затем в вашем Dockerfile установите свои требования как часть ENTRYPOINT заявление (или CMD заявления), а не как . Это важно, потому что (как указано в комментариях) крепление недоступно во время построения образа (когда RUN операторы выполняются). Файл Docker должен выглядеть так:

FROM my/base

ADD . /srv

ENTRYPOINT ["sh", "-c", "pip install -r requirements.txt && python setup.py install && run_server"]

вероятно, лучше всего, если каталог pip по умолчанию хост-системы будет использоваться в качестве кэша (например,$HOME/.cache/pip/ на Linux или $HOME/Library/Caches/pip/ на OSX), так же, как я предложил в Примере .

я обнаружил, что лучший способ-просто добавить каталог Python site-packages в качестве Тома.

services:
    web:
        build: .
        command: python manage.py runserver 0.0.0.0:8000
        volumes:
            - .:/code
            -  /usr/local/lib/python2.7/site-packages/

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

EDIT: Не обращайте внимания на этот ответ,jkukul это ответ выше работал для меня. Мое намерение состояло в том, чтобы кэшировать site-packages. Это выглядело бы примерно так:

volumes:
   - .:/code
   - ./cached-packages:/usr/local/lib/python2.7/site-packages/

кэширование папки Загрузки много хотя чище. Это также кэширует колеса, поэтому он правильно выполняет задачу.