从特定步骤重建docker图像

时间:2016-02-02 12:58:51

标签: docker dockerfile

我有下面的Dockerfile。

FROM ubuntu:14.04
MAINTAINER Samuel Alexander <samuel@alexander.com>

RUN apt-get -y install software-properties-common
RUN apt-get -y update

# Install Java.
RUN echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | debconf-set-selections
RUN add-apt-repository -y ppa:webupd8team/java
RUN apt-get -y update
RUN apt-get install -y oracle-java8-installer
RUN rm -rf /var/lib/apt/lists/*
RUN rm -rf /var/cache/oracle-jdk8-installer

# Define working directory.
WORKDIR /work

# Define commonly used JAVA_HOME variable
ENV JAVA_HOME /usr/lib/jvm/java-8-oracle

# JAVA PATH
ENV PATH /usr/lib/jvm/java-8-oracle/bin:$PATH

# Install maven
RUN apt-get -y update
RUN apt-get -y install maven

# Install Open SSH and git
RUN apt-get -y install openssh-server
RUN apt-get -y install git

# clone Spark
RUN git clone https://github.com/apache/spark.git
WORKDIR /work/spark
RUN mvn -DskipTests clean package

# clone and build zeppelin fork
RUN git clone https://github.com/apache/incubator-zeppelin.git
WORKDIR /work/incubator-zeppelin
RUN mvn clean package -Pspark-1.6 -Phadoop-2.6 -DskipTests

# Install Supervisord
RUN apt-get -y install supervisor
RUN mkdir -p var/log/supervisor

# Configure Supervisord
COPY conf/supervisord.conf /etc/supervisor/conf.d/supervisord.conf

# bash
RUN sed -i s#/home/git:/bin/false#/home/git:/bin/bash# /etc/passwd

EXPOSE 8080 8082
CMD ["/usr/bin/supervisord"]

在构建图像时,它在步骤23中失败,即

RUN mvn clean package -Pspark-1.6 -Phadoop-2.6 -DskipTests

现在当我重建时,它开始从步骤23开始构建,因为docker正在使用缓存。

但是,如果我想重建步骤21中的图像,即

RUN git clone https://github.com/apache/incubator-zeppelin.git

我该怎么做? 删除缓存的图像是唯一的选择吗? 还有其他参数吗?

7 个答案:

答案 0 :(得分:35)

一种解决方法:

  1. 找到您要执行的步骤。
  2. 在该步骤之前进行简单的虚拟操作,如“RUN pwd”
  3. 然后只需构建您的Dockerfile。它将从缓存中取出所有内容,然后在伪命令之后执行这些行。

答案 1 :(得分:31)

您可以通过执行

重建整个事物而不使用缓存
docker build --no-cache -t user/image-name

要强制从特定行开始重新运行,您可以传递一个未使用的arg。 Docker将ARG值作为环境变量传递给RUN命令,因此更改ARG是对命令的更改,该命令会破坏缓存。甚至不需要在RUN线上自己定义它。

FROM ubuntu:14.04
MAINTAINER Samuel Alexander <samuel@alexander.com>

RUN apt-get -y install software-properties-common
RUN apt-get -y update

# Install Java.
RUN echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | debconf-set-selections
RUN add-apt-repository -y ppa:webupd8team/java
RUN apt-get -y update
RUN apt-get install -y oracle-java8-installer
RUN rm -rf /var/lib/apt/lists/*
RUN rm -rf /var/cache/oracle-jdk8-installer

# Define working directory.
WORKDIR /work

# Define commonly used JAVA_HOME variable
ENV JAVA_HOME /usr/lib/jvm/java-8-oracle

# JAVA PATH
ENV PATH /usr/lib/jvm/java-8-oracle/bin:$PATH

# Install maven
RUN apt-get -y update
RUN apt-get -y install maven

# Install Open SSH and git
RUN apt-get -y install openssh-server
RUN apt-get -y install git

# clone Spark
RUN git clone https://github.com/apache/spark.git
WORKDIR /work/spark
RUN mvn -DskipTests clean package

# clone and build zeppelin fork, changing INCUBATOR_VER will break the cache here
ARG INCUBATOR_VER=unknown
RUN git clone https://github.com/apache/incubator-zeppelin.git
WORKDIR /work/incubator-zeppelin
RUN mvn clean package -Pspark-1.6 -Phadoop-2.6 -DskipTests

# Install Supervisord
RUN apt-get -y install supervisor
RUN mkdir -p var/log/supervisor

# Configure Supervisord
COPY conf/supervisord.conf /etc/supervisor/conf.d/supervisord.conf

# bash
RUN sed -i s#/home/git:/bin/false#/home/git:/bin/bash# /etc/passwd

EXPOSE 8080 8082
CMD ["/usr/bin/supervisord"]

然后用一个独特的arg运行它:

docker build --build-arg INCUBATOR_VER=20160613.2 -t user/image-name .

另外,我建议您进行以下更改以使图层更小,下载和安装后合并清除和删除单个RUN命令的步骤越多,最终图像越小将会。否则,您的图层将包含下载和清理之间的所有中间步骤:

FROM ubuntu:14.04
MAINTAINER Samuel Alexander <samuel@alexander.com>

RUN DEBIAN_FRONTEND=noninteractive \
    apt-get -y install software-properties-common && \
    apt-get -y update

# Install Java.
RUN echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | debconf-set-selections && \
    add-apt-repository -y ppa:webupd8team/java && \
    apt-get -y update && \
    DEBIAN_FRONTEND=noninteractive \
    apt-get install -y oracle-java8-installer && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* && \
    rm -rf /var/cache/oracle-jdk8-installer && \

# Define working directory.
WORKDIR /work

# Define commonly used JAVA_HOME variable
ENV JAVA_HOME /usr/lib/jvm/java-8-oracle

# JAVA PATH
ENV PATH /usr/lib/jvm/java-8-oracle/bin:$PATH

# Install maven
RUN apt-get -y update && \
    DEBIAN_FRONTEND=noninteractive \
    apt-get -y install 
      maven \
      openssh-server \
      git \
      supervisor && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# clone Spark
RUN git clone https://github.com/apache/spark.git
WORKDIR /work/spark
RUN mvn -DskipTests clean package

# clone and build zeppelin fork
ARG INCUBATOR_VER=unknown
RUN git clone https://github.com/apache/incubator-zeppelin.git
WORKDIR /work/incubator-zeppelin
RUN mvn clean package -Pspark-1.6 -Phadoop-2.6 -DskipTests

# Configure Supervisord
RUN mkdir -p var/log/supervisor
COPY conf/supervisord.conf /etc/supervisor/conf.d/supervisord.conf

# bash
RUN sed -i s#/home/git:/bin/false#/home/git:/bin/bash# /etc/passwd

EXPOSE 8080 8082
CMD ["/usr/bin/supervisord"]

答案 2 :(得分:7)

要完成德米特里的回答,您可以使用像date +%s这样的uniq arg来保持相同的指挥

docker build --build-arg DUMMY=`date +%s` -t me/myapp:1.0.0

Dockerfile

...
ARG DUMMY=unknown
RUN DUMMY=${DUMMY} git clone xxx
...

答案 3 :(得分:5)

一种更简单的技术。

Dockerfile:
添加此行,以便开始跳过缓存。

COPY marker /dev/null

然后使用

构建

date > marker && docker build .

答案 4 :(得分:4)

如果将ARG INCUBATOR_VER=unknown置于顶部,则在命令行更改INCUBATOR_VER的情况下不会使用缓存(刚刚测试了构建版本)。 对我来说工作:

# The rebuild starts from here
ARG INCUBATOR_VER=unknown
RUN INCUBATOR_VER=${INCUBATOR_VER} git clone https://github.com/apache/incubator-zeppelin.git

答案 5 :(得分:2)

另一种选择是删除要重建的缓存中间映像。

在构建输出中找到要重建的中间映像的哈希值:

true true

然后删除该图像:

Step 27/42 : RUN lolarun.sh
 ---> Using cache
 ---> 328dfe03e436

或者如果它给您带来错误并且您可以强制执行,则可以:

$ docker image rmi 328dfe03e436

最后,重新运行构建命令,由于它不在缓存中,因此需要从该位置重新启动。

答案 6 :(得分:0)

由于没有正式的方法可以执行此操作,所以最简单的方法是临时更改特定的RUN命令,使其包含无害的内容,例如echo:

RUN echo && apt-get -qq update && \
    apt-get install nano

构建后将其删除。