我正在使用一个生成大量文件的 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/