【问题标题】:OpenShift 3.1 - Prevent Docker from caching curl resourceOpenShift 3.1 - 防止 Docker 缓存 curl 资源
【发布时间】:2016-05-13 10:46:56
【问题描述】:

我的 Dockerfile 中有这个 curl 命令:

RUN curl -H 'Cache-Control: no-cache' -f ${NEXUS_URL}${ARTIFACT_PATH}-${ARTIFACT_VERSION}.war?nocache=true -o $JBOSS_HOME/standalone/deployments/ROOT.war

我第一次运行它时,我可以看到下载信息。然而,在那之后它似乎正在缓存远程资源,因此不再更新它:

Step 6 : RUN curl -H 'Cache-Control: no-cache' -f ${NEXUS_URL}${ARTIFACT_PATH}-${ARTIFACT_VERSION}.war?nocache=true -o $JBOSS_HOME/standalone/deployments/ROOT.war
30   ---> Using cache
31   ---> be50412bf6c3

我怎样才能防止这种情况发生?

【问题讨论】:

    标签: curl docker openshift dockerfile openshift-origin


    【解决方案1】:

    根据 OpenShift 文档 (https://docs.openshift.com/enterprise/3.1/dev_guide/builds.html#no-cache),您可以使用以下语法强制不缓存构建:

    strategy:
      type: "Docker"
      dockerStrategy:
        noCache: true
    

    这意味着不会缓存任何步骤,这会使您的构建变慢,但意味着您的构建中有正确的工件版本。

    【讨论】:

      【解决方案2】:

      您可以使用 ARG 在特定 Dockerfile 指令处破坏缓存。

      在 Dockerfile 中:

      ARG CACHEBUST=1
      RUN git clone https://github.com/octocat/Hello-World.git 
      

      在命令行上:

      docker build -t your-image --build-arg CACHEBUST=$(date +%s) . 
      

      将 CACHEBUST 设置为当前时间意味着它将始终 Dockerfile 中 ARG 声明后的唯一性和说明 不会被缓存。请注意,您也可以在不指定的情况下构建 CACHEBUST build-arg,这将导致它使用默认值 1 并保留缓存。这可用于始终检查新鲜 git repos 的副本,拉取最新的 SNAPSHOT 依赖项等。

      Source

      还有:

      您可以使用 --no-cache 或 --build-arg 使缓存无效。你 可以通过拥有一个包含所有内容的基础映像来最小化 --no-cache 的影响 可缓存的命令。

      Source

      【讨论】:

      • 我无法控制 docker 的运行方式,我的意思是我在调用我的 dockerfile 的 PaaS 中运行,因此我无法在 docker build 中传递参数 ...
      • 我给你一个 +1 作为最好的纯 Docker 答案
      • 那么当从 shell 运行时,使用 CACHEBUST 和 --no-cache 有区别吗?我的 dockerfile(间接)克隆了我正在积极更改的单独 git 存储库的一个分支。 (为了完全准确,它不是直接克隆第二个 repo,而是 pip 安装它。)我想有条件地破坏缓存,理想情况下仅适用于添加该单独 repo 的层,只要其远程分支的 HEAD 发生更改。我曾考虑从 GitHub 动态获取 HEAD 提交哈希并将其存储在添加到存储库的 ADD 命令上方的文件中,但对于常见场景来说感觉很hacky。
      【解决方案3】:

      我无法控制 docker 的运行方式,我的意思是我在调用我的 dockerfile 的 PaaS 中运行,因此我无法在 docker build 中传递参数

      您可以尝试控制 Dockerfile 的内容。

      如果您可以在让 PaaS 调用它之前重新生成 Dockerfile,这将有助于确保缓存无效:

      sed -i 's/ROOT.war.*/ROOT.war && echo $(date)'/g' Dockerfile
      

      【讨论】:

      • 不幸的是我也做不到。 PaaS 服务器从 Git 存储库获取我的 Dockerfile
      • 我绝对可以修改 Dockerfile,将新版本推送到 repo。然而,这也没有奏效。 PaaS 是 OpenShift 3.x。我开始一个新的构建设置将进入 Docker 的环境变量。每当我使用相同的 ARTIFACT_VERSION 开始构建时,它都会获得一个缓存的工件。
      • @codependent 是链接到 git repo 标签的 ARTIFACT_VERSION 吗?
      • 不,它用于从 Nexus 服务器下载 war 文件:${NEXUS_URL}${ARTIFACT_PATH}-${ARTIFACT_VERSION}.war
      • @codependent 所以它没有从 git repo 中检测到新版本?
      【解决方案4】:

      我知道这是一个老问题,但我认为我的解决方案比上面的解决方案更好。您可以在特定点使缓存无效,而不是完全删除缓存。在我看来,最好的方法是:

      # No caching from now on!
      ADD http://worldclockapi.com/api/json/utc/now build_time.json
      

      即获取文件中的当前时间,每次运行时都会有所不同,从而使缓存无效。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-21
        • 2012-05-01
        • 1970-01-01
        • 2012-03-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多