如何在 Dockerfile 中添加大型 HTTP 文件并将其从镜像层中排除?

2024-04-23

Our Nexus服务器 http://www.sonatype.com/nexus/product-overview为我们的 Java 项目提供构建工件,包括其安装程序。那个安装程序是真的很大(>1GB)。我想检索并使用它Dockerfile.

到目前为止我所做的如下:

FROM debian:jessie
...
RUN apt-get install -y curl xmllib-xpath-perl
ENV PROJECT_VERSION x.y.z-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
...

通过这种方法,我能够:

  • 查询 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 x.y.z-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 file.
  • 无法阻止将安装程序存储在映像层中。

但至少这会使用适当的缓存来重新使用旧安装程序版本的现有映像层,并在 Nexus 上部署新安装程序版本时创建新映像层。

所以问题是:如何同时启用正确的缓存、缓存失效以及从 Docker 映像层中排除大安装程序文件?

EDIT:我找到了一种通过使用其他 Nexus API 使图像层缓存正常工作的方法:

FROM debian:jessie
...
ENV PROJECT_VERSION x.y.z-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声明但同时不将添加的文件包含到图像历史记录中?


我接受米科拉·古罗夫 https://stackoverflow.com/users/243861/mykola-gurov我的回答是因为在他的一条评论中,他指出了一个帮助我解决这个问题的想法。

以下是我为实现正确的缓存和缓存失效以及排除大安装程序文件所做的操作:

FROM debian:jessie
...
RUN apt-get install -y curl
ENV PROJECT_VERSION x.y.z-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 上的元数据被修改时,缓存就会失效。

The ADD在这种情况下,执行其所有后续指令时不会重新使用任何缓存版本。

如果服务器上的元数据自上次下载以来没有更改ADD以及以下内容RUN执行的指令curl从图像层缓存中获取。并且在RUN可以一步下载、执行和删除临时大安装程序文件,而无需将其存储在任何映像层中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Dockerfile 中添加大型 HTTP 文件并将其从镜像层中排除? 的相关文章

随机推荐

  • 如何在 Entity Framework 4.1 的 Code-First Fluent API 中以编程方式定义关系

    我正在玩新的 EF4 1 unicorn love 我试图了解我可以使用的不同方式代码优先 to 以编程方式定义几个简单 POCO 之间的关系 我如何定义以下 gt 1 Team有0 多Users 和一个User是在 1Team 1 Use
  • djangorest框架模型序列化器 - 嵌套读取,扁平写入

    我遇到一种情况 我的客户正在尝试编写包含 fk 列表的表示 languages 1 last name Beecher settings 1 state NY 但是当读它时 我想要一个嵌套表示来减少往返次数 languages id 1 c
  • 在 Atom 中使用变量创建片段

    是否可以将变量合并到 Atom 中的片段中 例如 当您想要预先填充即将出现的点时 这对于 for 循环非常有用 The snippets cson我想以java作为源的条目 不幸的是它不起作用 source java For Loop pr
  • MobX 自动运行行为

    我正在探索 MobX 并对一个问题感兴趣 如果我有这个可观察的 class ItemsStore observable items 1 2 3 const store new ItemsStore 然后像这样改变它 setInterval
  • Django Admin:为两个管理站点使用不同的模板

    我有一个 Django 项目 有两个不同的管理站点 如中所述文档 http docs djangoproject com en 1 2 ref contrib admin multiple admin sites in the same u
  • 完美平衡二叉搜索树

    我有一个理论问题Balanced BST 我想建立Perfect Balanced Tree具有2 k 1节点 从常规unbalanced BST 我能想到的最简单的解决方案是使用排序Array Linked list并递归地将数组划分为子
  • R 合并具有相似值的行

    我有一个数据框 行值首先从小到大排序 我计算相邻行之间的行值差异 组合具有相似差异 例如 小于 1 的行 并返回组合行的平均值 我可以使用 for 循环检查每一行的差异 但这似乎是一种非常低效的方法 还有更好的想法吗 谢谢 library
  • Rails 对 :dependent => :destroy 和级联删除/无效/限制做什么

    我正在尝试决定如何最好地为我的 Rails 应用程序设置 如果有的话 外键约束 我有一个模型Response that belongs to a Prompt 我想用 dependent gt destroy摧毁每一个Response属于已
  • 如何在 Java 的 JTextPane 中创建自动完成弹出窗口?

    我正在创建一个 SQL 编辑器 我使用 JTextPane 作为编辑器 我想像 Eclipse 一样实现表名等的自动完成 我认为在另一个组件之上显示信息的适当类是JPopupMenu 它已经正确处理分层以显示自身 JPopupMenu 有一
  • Android 中的自定义键盘视图

    我正在开发一个自定义 Android 键盘 我开始开发我的键盘 基于this http code tutsplus com tutorials create a custom keyboard on android cms 22615教程
  • 对heroku postgresql DB的访问只能仅限于它的heroku应用程序吗?

    由于安全顾问的建议 我最近将一个应用程序从 heroku 迁移到 amazon ec2 然而 他对 Heroku 的了解并不深 疑问仍然存在 对 Heroku PostgreSQL 数据库的访问是否可以限制为只能由应用程序访问 您会推荐 H
  • 在 Windows Server 2003 中将控制台应用程序安装为 Windows 服务

    这可能是一个基本问题 所以提前道歉 我有一个控制台应用程序 我想在 Windows Server 2003 上测试它 我使用 4 0 框架在 C 中以发布模式构建了该应用程序 并将 bin 文件夹的内容粘贴到 windows server
  • 在 Objective-C 中以编程方式创建 .pem 文件?

    我正在尝试使用 iPhone 应用程序中的 Objective C 和 OpenSSL 库以编程方式从证书签名请求创建 PEM 文件 我按照 Adria Navarro 对这个问题的回答生成了 CSR 类型为 X509 REQ 使用钥匙串存
  • 从 Java / C# 角度理解 C++ 编译器

    我是一名经验丰富的 Java C 程序员 最近开始学习 C 问题是 我无法理解如何构建各种头文件和代码文件 这似乎主要是由于我对编译器如何将所有内容链接在一起缺乏了解 我尝试阅读一些教科书 但我的先入之见受到我的 Java 和 C 知识的影
  • 使用 AVPlayer 播放流媒体视频

    如何播放流媒体视频AVPlayer import Cocoa import AVKit class StreamViewController NSViewController var videoPlayer AVPlayer IBOutle
  • maven中这两个设置一样吗?

    我想限制maven仅使用私有 非公共maven存储库 这两个设置具有相同的效果吗 1 settings xml中设置镜像
  • 使用jquery mobile在页面之间传递参数

    jquery mobile 中页面之间传递参数的正确方法是什么 在jquery mobile的Q A中 有一些插件的建议 是强制性的吗 请告诉我正确的方法 没有一个具体的答案 我必须为页面中的所有链接传递参数 http view jquer
  • Mercurial .hgrc 文件

    默认情况下 在 Windows XP 上 Mercurial 将 hgrc 文件存储在 好吧 就我而言 c Documents and Settings srooks 我如何更改该位置 并让它在其中查找 hgrc 文件 例如 c Confi
  • 在哪里可以找到 Hyperledger Fabric peer 命令可能的环境变量?

    配置对等节点运行时 示例 docker compose 文件中包含许多环境变量 有什么地方可以找到它们的全部记录吗 e g environment CORE VM ENDPOINT unix host var run docker sock
  • 如何在 Dockerfile 中添加大型 HTTP 文件并将其从镜像层中排除?

    Our Nexus服务器 http www sonatype com nexus product overview为我们的 Java 项目提供构建工件 包括其安装程序 那个安装程序是真的很大 gt 1GB 我想检索并使用它Dockerfil