Повторная установка пакета внутри образа докера

1265
Tejas Jayasheel

Я создал пакет под названием Python my-package. Я не собираюсь делать это общедоступным, поэтому установка происходит в основном через наши внутренние серверы. Недавно один старший разработчик создал архитектуру с использованием докера, где приложение размещено и my-packageявляется зависимостью.

Проблема в том, чтобы протестировать пакет, мне ПОВТОРНО нужно скопировать мой код в образ докера, затем удалить старую версию пакета и переустановить из локального кода.

  1. Восстановление всего изображения снова занимает полчаса. - Не вариант.
  2. Создайте еще один Dockerfile FROM из существующего образа и выполните только определенные команды, чтобы скопировать и установить пакет pip. - Мое текущее решение пока не очень эффективно.

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

ОБНОВЛЕНИЕ: Dockerfile

# VERSION 1.8.2 # AUTHOR: Matthieu "Puckel_" Roisil # DESCRIPTION: Basic Airflow container # BUILD: docker build --rm -t puckel/docker-airflow . # SOURCE: https://github.com/puckel/docker-airflow  FROM ubuntu:17.10 MAINTAINER Puckel_  # Never prompts the user for choices on installation/configuration of packages ENV DEBIAN_FRONTEND noninteractive ENV TERM linux  # Airflow ARG AIRFLOW_VERSION=1.8.9 ARG AIRFLOW_HOME=/usr/local/airflow  # Define en_US. ENV LANGUAGE en_US.UTF-8 ENV LANG en_US.UTF-8 ENV LC_ALL en_US.UTF-8 ENV LC_CTYPE en_US.UTF-8 ENV LC_MESSAGES en_US.UTF-8 ENV LC_ALL en_US.UTF-8  ENV MATPLOTLIBRC /etc  RUN set -ex \ && buildDeps=' \ python3.6-dev \ libkrb5-dev \ libsasl2-dev \ libssl-dev \ libffi-dev \ build-essential \ libblas-dev \ liblapack-dev \ libpq-dev \ git \ wget \ ' \ && apt-get update -yqq \ && apt-get dist-upgrade -yqq \ && apt-get install -yqq --no-install-recommends \ $buildDeps \ python3.6 \ python3.6-tk \ apt-utils \ curl \ netcat \ locales \ ca-certificates \ sudo \ libmysqlclient-dev \ && ln -s /usr/bin/python3.6 /usr/bin/python \ && sed -i 's/^# en_US.UTF-8 UTF-8$/en_US.UTF-8 UTF-8/g' /etc/locale.gen \ && locale-gen \ && update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 \ && useradd -ms /bin/bash -d $ -u 1500 airflow \ && mkdir $/logs \ && wget https://bootstrap.pypa.io/get-pip.py \ && python get-pip.py \ && rm -rf get-pip.py \ && python -m pip install Cython \ && python -m pip install requests \ && python -m pip install pytz \ && python -m pip install pyOpenSSL \ && python -m pip install ndg-httpsclient \ && python -m pip install pyasn1 \ && python -m pip install Flask-OAuthlib \ && python -m pip install apache-airflow[crypto,celery,postgres,ldap,jdbc,mysql,s3,samba]==$AIRFLOW_VERSION \ && python -m pip install celery[redis]==4.1.0 \ && python -m pip install boto3 \ && python -m pip install pymongo \ && python -m pip install statsd \  && apt-get remove --purge -yqq $buildDeps \ && apt-get clean \ && rm -rf \ /var/lib/apt/lists/* \ /tmp/* \ /var/tmp/* \ /usr/share/man \ /usr/share/doc \ /usr/share/doc-base \ && apt-get autoremove -yqq 

Важная часть в конце.

ARG CACHEBUST=1  COPY config/matplotlibrc /etc/matplotlibrc COPY script/entrypoint.sh /entrypoint.sh COPY script/shell.sh /shell.sh COPY config/airflow.cfg $/airflow.cfg  RUN chown -R airflow: $  RUN pip install matplotlib seaborn xlsxwriter pandas Jinja2 #Add custom PIP repo - THIS IS OF INTEREST COPY config/pip.conf /etc/pip.conf  RUN python -m pip install my-package  COPY my-package2 /usr/local/my-package2 # RUN pip uninstall my-package2 RUN python -m pip install /usr/local/my-package2  EXPOSE 8080 5555 8793  USER airflow WORKDIR $ ENTRYPOINT ["/entrypoint.sh"] 

Как видите, я копирую my-package2 с моего локального компьютера в образ и запускаю pip install.

  1. Размер изображения увеличивается с каждым разом, когда я перестраиваю его.
  2. Объемы, безусловно, вариант, который я еще не пробовал. Я уже использую то, script/shell.sh что только что $@. Я устанавливаю это как точку входа и запускаю любую команду, которую хочу запустить внутри изображения без особых затруднений.
  3. Я использую docker-compose, поэтому каждый раз, когда я перестраиваюсь с новым тегом, мне нужно также обновлять в docker-compose. Со временем это становится раздражающим, чтобы сделать это из-за однострочного изменения кода.
0
Почему это не будет эффективным? Кроме того, что касается перестроения изображения, если вы сделаете его дополнительным слоем, оно должно улучшить время, поскольку у вас будут промежуточные звенья (при условии, что вы не удаляете их каждый раз). По крайней мере, я так понимаю Docker. Seth 6 лет назад 1
Не очень эффективно, потому что 1. Размер изображения увеличивается с каждой попыткой (не знаю почему. Технически это не должно), и моему компьютеру Mac не хватает памяти. 2. Необходимо повторно пометить, перестроить и удалить старый тег при каждой попытке. Довольно громоздкий процесс. Tejas Jayasheel 6 лет назад 1
Я думаю, что идея здравая (плюс кажется, что для вас решено, что Docker должен быть использован). Я думаю, что было бы лучше сосредоточиться на вопросе о необходимости многократного копирования вашего кода. Кроме того, когда вы меняете один слой изображения докера, это не должно занимать полчаса. Может быть, вы можете изменить порядок, в котором вы делаете вещи, или получить более быстрый компьютер. Чтобы дать совет по этому вопросу, нам определенно понадобилось бы гораздо больше деталей. mtak 6 лет назад 0
Не могли бы вы поделиться достаточным количеством вашего dockerfile, чтобы мы могли понять, почему установка пакета pip занимает столько времени. Но сначала вопрос: почему бы вам вместо создания образа для тестирования просто использовать пакет с хоста через параметр `-v / path / on / host: / path / in / container`? harrymc 6 лет назад 0
@harrymc Обновлен файл докера и несколько комментариев о моих испытаниях. Tejas Jayasheel 6 лет назад 0
@mtak обновляется с помощью dockerfile Tejas Jayasheel 6 лет назад 0
Почти весь dockerfile устанавливает зависимости. Почему бы вам не создать изображение, содержащее их все, просто повторяя последние несколько шагов для тестирования каждый раз? harrymc 6 лет назад 1

1 ответ на вопрос

1
harrymc

Вам нужно будет поделиться некоторыми своими файлами dockerfile, чтобы мы могли понять, почему установка пакета pip занимает столько времени. Если вы хотите оптимизировать его, эти ссылки могут помочь:

Альтернативное решение состоит в том, чтобы вместо создания образа для тестирования просто использовать пакет с хоста с помощью параметра Docker of -v /host/directory:/container/directory.

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

Можно найти гораздо больше информации, например: Общие сведения о томах в Docker .


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

Для удобства чтения вы можете, наконец, написать файл Docker как многоэтапный, чтобы отделить создание зависимостей от производства и, возможно, также создать только окончательную минимальную сборку. Инструкция ONBUILD может быть полезным здесь.

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

Спасибо за предложение. Я закончил с комбинацией двух решений, которые вы упомянули. В `docker-compose` я установил объем так, чтобы код пакета был разделен между контейнером и хостом. Как только код пакета стабилизируется, я перестроил следующую версию изображения, используя `ONBUILD`. Хотя повторное копирование увеличивает размер изображения, так как КОПИЯ не так часто, как раньше, я могу жить с этим. Tejas Jayasheel 6 лет назад 0

Похожие вопросы