我们的 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
...
通过这种方法,我能够:
${PROJECT_VERSION}
提供最新的 SNAPSHOT 版本在 docker build
期间注销有什么不见了:
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/