Назад | Перейти на главную страницу

Создать образ Docker с кешем на сервере сборки?

У нас есть CI-сервер Jenkins, который извлекает наш код из Git, собирает его, создает образ Docker, а затем отправляет его на некоторые производственные серверы.

Наш проект в основном написан на Python, поэтому "сборка" включает в себя запуск

pip install -r requirements.txt

Это работает нормально, только медленно. Он должен получать пакеты по сети, плюс он должен создавать библиотеки C для некоторых из них (а lxml не маленький!).

В разработке я успешно использовал pip-accel чтобы ускорить этот процесс. Он имеет тот же интерфейс, что и pip но он кэширует как загрузки Python, так и встроенный код C, поэтому

pip-accel install -r requirements.txt

быстро.

Я хочу сделать это для наших производственных сборок, но сталкиваюсь с некоторыми препятствиями.

Очевидно, pip-accel нужен каталог для хранения кеша. Поскольку наш CI-сервер - это то, что запускает сборки, это логичное место для его размещения. Но pip install команда выполняется внутри нового контейнера Docker, поэтому она не может просто получить доступ к общему каталогу на этом сервере.

Кажется, что «тома» Docker предназначены для совместного использования каталогов с контейнерами, но наша сборка происходит (неожиданный сюрприз) внутри docker build, и только docker run позволяет прикреплять тома. Вы не можете прикреплять тома с docker build.

Что-то мне не хватает? Как я могу запустить docker build и поделиться папкой кеша с моим хостом вне контейнера, в котором я нахожусь?

У меня мало репутации, чтобы комментировать ваш вопрос, поэтому в моем ответе тоже есть несколько вопросов.

Я попытался создать ту же настройку, что и ваш, но минифицирован (на основе вашего объяснения выше), и, похоже, есть улучшения с собственными механизмами кеширования докера

Мой пример Dockerfile выглядит так:

FROM ubuntu:14.04   

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

COPY requirements.txt /requirements.txt

RUN pip-accel install -r /requirements.txt

CMD tail -f /dev/null

А файл requirements.txt выглядел так:

Flask==0.8
Jinja2==2.6
Werkzeug==0.8.3

Создав это в первый раз (посмотрите дольше), я добавил новую библиотеку chardet == 1.0.1, и теперь мой файл requirements.txt выглядел так:

Flask==0.8
Jinja2==2.6
Werkzeug==0.8.3
chardet==1.0.1

После запуска сборки докера он использовал весь собственный кеш докера, в котором также были старые библиотеки pip

anovil@anovil-Latitude-E6440:~/tmp/serverfault/docker$ time docker build --rm .
Sending build context to Docker daemon 3.072 kB
Step 1 : FROM ubuntu:14.04
 ---> 89d5d8e8bafb
...
...
Removing intermediate container 337c23340e7a
Step 5 : CMD tail -f /dev/null
 ---> Running in 5cb25bc75bbe
 ---> d3dfe184934b
Removing intermediate container 5cb25bc75bbe
Successfully built d3dfe184934b

real    0m6.325s
user    0m0.024s
sys 0m0.012s

Потому что сборка докеров по умолчанию имеет '--force-rm = false', '--no-cache = false'.
Другое дело, если ваш Jenkins CI запускает эту сборку от имени разных пользователей или на разных хостах. В противном случае нужно упорядочить команды в Dockerfile.
Если у вас все еще есть вопросы, можете ли вы поделиться своим образцом Dockerfile, а также сообщить здесь, насколько / часто ваш файл requirements.txt изменяет каждую сборку jenkins.