java - 提交在/workspace 中生成的文件的容器更改(即使使用 makefile)不会持续到图像的新实例中

标签 java bash docker antlr dockerfile

我正在使用一个生成大量文件的 java 程序(即 ANTLR 使用语法生成解析器)。当我表演时:

java -cp "/usr/local/lib/antlr-4.5-complete.jar:$CLASSPATH" org.antlr.v4.Tool Java8.g4 && javac *.java

在使用 docker 镜像的交互式 shell 中,某些 java 文件及其类在当前目录中生成。

但是当我在 Dockerfile 中使用以下命令执行此操作时:

RUN java -cp "/usr/local/lib/antlr-4.5-complete.jar:$CLASSPATH" org.antlr.v4.Tool Java8.g4 && javac *.java

文件似乎没有生成。

发生这种情况的任何原因以及我如何更正此问题以使用 Dockerfile 中的 RUN 指令生成文件?

更新 1: 更多信息,我的 Dockerfile 如下所示:

FROM blah/blah_java
MAINTAINER blabla
RUN apt-get install -y make wget
RUN mkdir -p /usr/java && wget -O java.tar.gz http://download.oracle.com/otn-pub/java/jdk/8u40-b25/jdk-8u40-linux-x64.tar.gz --header "Cookie: oraclelicense=accept-securebackup-cookie" && tar xfz java.tar.gz -C /usr/java
ENV JAVA_HOME /usr/java/jdk1.8.0_40
ENV PATH $PATH:$JAVA_HOME/bin
      .
      .
      .
RUN mkdir -p /usr/local/lib && cd /usr/local/lib && wget http://www.antlr.org/download/antlr-4.5-complete.jar
ENV CLASSPATH=".:/usr/local/lib/antlr-4.5-complete.jar:$CLASSPATH"
      .
      .
      .
RUN mkdir -p /workspace/antlr-test/
ADD Java8.g4 /workspace/antlr-test/
WORKDIR /workspace/antlr-test/
RUN java -cp "/usr/local/lib/antlr-4.5-complete.jar:$CLASSPATH" org.antlr.v4.Tool Java8.g4 && javac *.java

更新 2: 在建筑上输出类似这样的东西:

Step 1 : FROM blah/blah_java
 ---> ff083dedeeac
Step 2 : MAINTAINER blabla
 ---> Using cache
 ---> b2cc75d73e93
Step 3 : RUN apt-get install -y make wget
 ---> Using cache
 ---> e8f8162ca496
Step 4 : RUN mkdir -p /usr/java && wget -O java.tar.gz http://download.oracle.com/otn-pub/java/jdk/8u40-b25/jdk-8u40-linux-x64.tar.gz --header "Cookie: oraclelicense=accept-securebackup-cookie" && tar xfz java.tar.gz -C /usr/java
 ---> Using cache
 ---> 1587950d483a
Step 5 : ENV JAVA_HOME /usr/java/jdk1.8.0_40
 ---> Using cache
 ---> 1787ea5c62c4
Step 6 : ENV PATH $PATH:$JAVA_HOME/bin
 ---> Using cache
 ---> 5f9082023d2c
       .
       .
       .
Step 10 : RUN mkdir -p /usr/local/lib && cd /usr/local/lib && wget http://www.antlr.org/download/antlr-4.5-complete.jar
 ---> Using cache
 ---> 7a67f6c4c572
Step 11 : ENV CLASSPATH ".:/usr/local/lib/antlr-4.5-complete.jar:$CLASSPATH"
 ---> Using cache
 ---> c64a24b809f0
        .
        .
        .
Step 14 : RUN mkdir -p /workspace/antlr-test/
 ---> Using cache
 ---> 27b18aab274f
Step 15 : ADD Java8.g4 /workspace/antlr-test/
 ---> Using cache
 ---> 87ace495d90b
Step 16 : WORKDIR /workspace/antlr-test/
 ---> Using cache
 ---> 31089935532b
Step 17 : RUN java -cp "/usr/local/lib/antlr-4.5-complete.jar:$CLASSPATH" org.antlr.v4.Tool Java8.g4 && javac *.java
 ---> Using cache
 ---> 773c302ecf5e
Successfully built 773c302ecf5e

更新 3: 在最后一个 RUN 指令中使用 'ls' 作为:

RUN java -cp "/usr/local/lib/antlr-4.5-complete.jar:$CLASSPATH" org.antlr.v4.Tool Java8.g4 && javac *.java && ls -la

我发现生成的文件被正确列出。在提交更改时这是行不通的。

更新 4: 我还发现在图像的交互式 shell 中,生成了文件。但是当我提交更改时,下次运行它们时它们将不可见。在执行 `docker diff 时,在提交更改之前,我发现生成的文件没有在此处监听。

更新 5: 如果生成的文件位于/workspace 目录中的子目录之一,则生成的文件似乎不会跨图像构建/提交保留。如果让它们生成外部工作区,它们似乎会通过构建/提交持续存在。

最佳答案

Docker 保留旧的构建步骤作为优化(这是 docker 优势的一部分)。

如果您更改 Dockerfile 并构建,新镜像将在更改之前为所有内容使用缓存,并在更改之后重建所有内容。

恢复 Dockerfile 中更改的行将重新激活缓存的构建。

您可以通过标记 docker build 使缓存失效,或者您可以在 Dockerfile 中添加行以提醒您最后使该部分以下的所有内容失效。例如,添加/编辑以下行将使它下面的缓存失效。

ENV FORCED_DOCKER_REBUILD=2018-01-01

关于java - 提交在/workspace 中生成的文件的容器更改(即使使用 makefile)不会持续到图像的新实例中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36397719/

相关文章:

java - 无法让循环正常工作

python - 为什么 '#!/usr/bin/env python' 据说比 '#!/usr/bin/python' 更正确?

linux - 编写一个函数来用硬链接(hard link)替换重复文件

mysql - Docker Compose mysql 环境变量与 Application .env 数据库变量。很困惑

amazon-web-services - 将实例注册到 AWS ECS 集群

java - 使用 @inject 和 applicationContext.xml 进行注入(inject)的区别

java - 当我从 Java 中的 ArrayList 中删除 1 个对象时。接下来会发生什么?

c - 如何禁止同一文件的多个 fopen()

docker - 当我们拥有 WebDeploy 时,为什么要为 .NET Web 应用程序使用 Docker?

java - 错误: Super must be first statement in constructor