Intereting Posts
Редактирование файлов из файла dockerfile Правила оповещения Прометея с ярлыком докеры работают только с префиксом «container_label_»? поддержка virsh для докеров Как обновить файл конфигурации через Dockerfile Может ли Jprofile подключаться к JVM, работающему в докере? docker – не может найти учетные данные aws в контейнере, хотя они существуют swift build faild из-за «базы данных заблокирован» в докер-контанере? Будет ли единый контейнер для докеров загружаться автоматически на EC2 Amazon? Ошибки докодера Как сохранить приложение консоли .NET Core в контейнере Docker Если докер использует виртуальную машину для запуска на Mac, то в чем ее преимущество перед бродягой? Ошибка при запуске npm install при создании файла docker: npm ERR! git clone git @ Обратный прокси Nginx: установите правильные порты с помощью jwilder / nginx-proxy для контейнера gitlab Где находится обратная конфигурация прокси-сервера в файле-докере artifactory-registry Ошибки при совместном использовании сетевого ресурса с хостом

Как добавить большие файлы HTTP в файл Docker и исключить их из слоев изображения?

Наш сервер Nexus предоставляет сборку артефактов для нашего Java-проекта, включая его установщика. Этот установщик действительно большой (> 1 ГБ). Я хотел бы получить и использовать его в Dockerfile .

То, что я сделал до сих пор, следующее:

 FROM debian:jessie ... RUN apt-get install -y curl xmllib-xpath-perl ENV PROJECT_VERSION xyz-SNAPSHOT ... RUN VERSION=`curl --silent "http://nexus:8081/service/local/artifact/maven/resolve?r=public&g=my.group.id&a=installer&v=${PROJECT_VERSION}&e=sh&c=linux64" | xpath -q -s '' -e '//data/version/text()'` \ && echo Version:\'${VERSION}\' \ && curl --silent http://nexus/content/groups/public/my/group/id/installer/${PROJECT_VERSION}/installer-${VERSION}-linux64.sh \ --create-dirs \ --output ${INSTALL_DIR}/installer.sh \ && sh ${INSTALL_DIR}/installer.sh <someArgs> \ && rm ${INSTALL_DIR}/installer.sh ... 

При таком подходе я могу:

  • Query Nexus для предоставления последней версии SNAPSHOT для предоставленного ${PROJECT_VERSION} который выходил из системы во время docker build
  • Используйте эту версию для загрузки соответствующего двоичного файла установщика
  • Выполнить двоичный файл установщика
  • Удалите двоичный файл установщика сразу после выполнения, чтобы он не был сохранен в пределах созданного слоя Docker

Чего не хватает:

  • Всякий раз, когда новый установщик развертывается в Nexus, мне нужно создать образ Docker с помощью docker build --no-cache . В противном случае Docker не сможет сделать недействительным свой кеш и повторно запустить шаг установки для более нового установщика, который тем временем был развернут в Nexus.

Поэтому я попробовал другой подход, используя инструкцию ADD поскольку у них есть возможности кэширования в соответствии с документацией. Но это не сработает, так как мне нужно предоставить параметр для инструкции ADD , заданной предыдущим шагом, запрашивающим Nexus для правильной версии SNAPSHOT:

 FROM debian:jessie ... RUN apt-get install -y curl xmllib-xpath-perl ENV PROJECT_VERSION xyz-SNAPSHOT ... ADD http://nexus:8081/service/local/artifact/maven/resolve?r=public&g=my.group.id&a=installer&v=${PROJECT_VERSION}&e=sh&c=linux64 ${INSTALL_DIR}/version.xml RUN cat ${INSTALL_DIR}/version.xml | xpath -q -s '' -e '//data/version/text()' > ${INSTALL_DIR}/version.txt # FIXME: Somehow do a `cat ${INSTALL_DIR}/version.txt to set the ENV ${VERSION} variable ?! ADD http://nexus/content/groups/public/my/group/id/installer/${PROJECT_VERSION}/installer-${VERSION}-linux64.sh ${INSTALL_DIR}/installer.sh RUN ${INSTALL_DIR}/installer.sh <someArgs> && rm ${INSTALL_DIR}/installer.sh ... 

Такой подход не работает, потому что:

  • Невозможно установить переменную среды ${VERSION} в Dockerfile к версии, хранящейся в файле version.txt .
  • Невозможно предотвратить установку установщика в пределах слоя изображения.

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

Поэтому возникает вопрос : как включить надлежащее кэширование, недействительность кэша и исключение большого файла установщика из слоев изображения Docker одновременно?

EDIT : я нашел способ обеспечить правильное кэширование слоев изображения, используя другой API Nexus:

 FROM debian:jessie ... ENV PROJECT_VERSION xyz-SNAPSHOT ... ADD http://nexus:8081/service/local/artifact/maven/content?r=public&g=my.group.id&a=installer&v=${PROJECT_VERSION}&e=sh&c=linux64 ${INSTALL_DIR}/installer.sh RUN sh ${INSTALL_DIR}/installer.sh <someArgs> \ && rm ${INSTALL_DIR}/installer.sh ... 

Но все же проблема наличия очень большого файла установщика, включенного в слои изображения, сохраняется, так как в этом коде не используется механизм ADD .

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

    Как насчет выполнения curl / wget, установки и удаления в одной длительной команде?

    Обновление в сочетании с ADD меньшего ресурса, см. Подробный ответ TC.

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

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

     FROM debian:jessie ... RUN apt-get install -y curl ENV PROJECT_VERSION xyz-SNAPSHOT ... ADD http://nexus:8081/service/local/artifact/maven/resolve?r=public&g=my.group.id&a=installer&v=${PROJECT_VERSION}&e=sh&c=linux64 ${INSTALL_DIR}/installer.xml RUN curl --silent "http://nexus:8081/service/local/artifact/maven/content?r=public&g=my.group.id&a=installer&v=${PROJECT_VERSION}&e=sh&c=linux64" \ --output ${INSTALL_DIR}/installer.sh \ && sh ${INSTALL_DIR}/installer.sh <someArgs> \ && rm ${INSTALL_DIR}/installer.sh ... 

    Первый ADD загружает метаданные Maven для запрошенного артефакта. Этот XML-файл довольно мал. Он использует правильное кэширование, поэтому всякий раз, когда метаданные в Nexus были изменены, кеш становится недействительным.

    ADD и все последующие инструкции выполняются без повторного использования в этом случае кешированных версий.

    Если метаданные на сервере не изменились с момента последней загрузки, ADD и следующая команда RUN которая выполняет curl , берутся из кеша слоя изображения. И в RUN можно загрузить, выполнить и удалить временный большой файл установщика за один шаг, не сохраняя его ни на одном слое изображения.