从特定步骤重建Docker映像

kqhtkvqz  于 2023-03-01  发布在  Docker
关注(0)|答案(8)|浏览(120)

我有下面的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

我该怎么做呢?删除缓存的图像是唯一的选择吗?有没有其他参数可以做到这一点?

kxkpmulp

kxkpmulp1#

您可以在不使用缓存的情况下重建整个内容,方法是执行

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 .

要在每次构建时更改参数,您可以将时间戳作为arg传递:

docker build --build-arg INCUBATOR_VER=$(date +%Y%m%d-%H%M%S) -t user/image-name .

或:

docker build --build-arg INCUBATOR_VER=$(date +%s) -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"]
rslzwgfq

rslzwgfq2#

一种解决方案:
1.找到要从中执行的步骤。
1.在此步骤之前,放置一个简单的虚拟操作,如“RUN pwd”
然后构建你的Dockerfile,它会该高速缓存中提取到这一步的所有内容,然后执行dummy命令之后的行。

c9qzyr3d

c9qzyr3d3#

要完成Dmitry的回答,可以使用uniqarg(如date +%s)来始终保持相同的命令行

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

Dockerfile

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

fsi0uk1n4#

更简单的方法。
停靠文件:
在希望开始跳过缓存的位置添加此行。
COPY marker /dev/null
然后使用
date > marker && docker build .

czfnxgou

czfnxgou5#

另一个选项是删除要重建的缓存中间映像。
在构建输出中找到要重新构建的中间映像的哈希值:

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

然后删除该图像:

$ docker image rmi 328dfe03e436

或者如果它给你一个错误,你可以强迫它:

$ docker image rmi -f 328dfe03e436

最后,重新运行您的构建命令,它将需要从该点重新启动,因为它不在该高速缓存中。

zlwx9yxi

zlwx9yxi6#

如果将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
nbysray5

nbysray57#

使用--cache-from=...选项并指定最后一个层的哈希值,以便在不重建的情况下重用。所有后续层都将重建。
假设我有以下缓存的Docker构建版本:

$ docker build -t pinger:latest .
Sending build context to Docker daemon  6.924MB
Step 1/5 : FROM ubuntu:latest
 ---> 58db3edaf2be
Step 2/5 : RUN echo "$(date)"
 ---> Using cache
 ---> b62b5deffedf
Step 3/5 : RUN apt-get update -y && apt-get install -y iputils-ping
 ---> Using cache
 ---> 02ba4da7d7a6
Step 4/5 : ENTRYPOINT ["ping"]
 ---> Using cache
 ---> dfd4c593d7be
Step 5/5 : CMD ["127.0.0.1"]
 ---> Using cache
 ---> 716cc6cbcf0e
Successfully built 716cc6cbcf0e
Successfully tagged pinger:latest

现在,如果我想强制apt-get stanza重新运行:

$ docker build --cache-from=b62b5deffedf -t pinger:latest .
Sending build context to Docker daemon  6.924MB
Step 1/5 : FROM ubuntu:latest
 ---> 58db3edaf2be
Step 2/5 : RUN echo "$(date)"
 ---> Using cache
 ---> b62b5deffedf
Step 3/5 : RUN apt-get update -y && apt-get install -y iputils-ping
 ---> Running in 0d96737075a6
...
ecbunoof

ecbunoof8#

由于没有正式的方法来实现这一点,最简单的方法是临时更改特定的RUN命令,使其包含一些无害的内容,如echo:

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

建造完成后,将其拆除。

相关问题