curl - 如何在 Dockerfile 中添加大的 HTTP 文件并将它们从图像层中排除?

标签 curl docker nexus dockerfile

我们的 Nexus server为我们的 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 为提供的 ${PROJECT_VERSION} 提供最新的 SNAPSHOT 版本在 docker build 期间注销
  • 使用该版本下载相应的安装程序二进制文件
  • 执行安装程序二进制文件
  • 执行后立即删除安装程序二进制文件到 没有将它存储在创建的 Docker 镜像层中

  • 有什么不见了:
  • 每当将新安装程序部署到 Nexus 时,我都必须使用 docker build --no-cache 构建 Docker 镜像。 .否则 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 中存储的版本文件。
  • 无法阻止将安装程序存储在镜像层中。

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

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

    编辑 :我找到了一种使用其他 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 提供的缓存及其正确失效中受益的任何想法声明但同时不将添加的文件包含到图像历史记录中?

    最佳答案

    我接受了 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 上的元数据被修改,缓存就会失效。
    ADD在这种情况下,它的所有后续指令都不会重新使用任何缓存版本而被执行。

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

    关于curl - 如何在 Dockerfile 中添加大的 HTTP 文件并将它们从图像层中排除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31785785/

    相关文章:

    java - jQAssistant - 减少内存消耗

    c++ - LIBCURL 中的简单 telnet 示例 - C++

    php - 使用 cURL 获取错误代码 28

    curl - 如何使用命令行curl显示请求 header

    php - 使用 CURL 检查网站是否使用 SSL

    reactjs - 在React Docker容器上的连接被拒绝

    nexus - Sonatype Nexus - 无法再使用管理员用户登录

    docker 镜像在构建后消失了

    docker - 如何从 Docker-for-mac 或 Docker-for-Windows 获取可浏览的 url?

    Maven 版本插件跳过更新检查