从特定步骤重建 docker 个图像
rebuild docker image from specific step
我有以下 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
我该怎么做?
删除缓存的图像是唯一的选择吗?
是否有任何其他参数可以做到这一点?
一个解决方法:
- 找到您要执行的步骤。
- 在该步骤之前放置一个简单的虚拟操作,如 "RUN pwd"
然后只需构建您的 Dockerfile。它将从缓存中获取该步骤之前的所有内容,然后执行虚拟命令之后的行。
您可以在不使用缓存的情况下重建整个内容,方法是
docker build --no-cache -t user/image-name
要强制从特定行开始重新运行,您可以传递一个未使用的 arg。 Docker 将 ARG 值作为环境变量传递给您的 运行 命令,因此更改 ARG 是对打破缓存的命令的更改。甚至没有必要在 运行 行上自己定义它。
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 .
要在每次构建时更改参数,您可以将时间戳作为参数传递:
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"]
如果将 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
要完成 Dmitry 的回答,您可以使用像 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
...
更简单的技术。
Dockerfile:
在您希望开始跳过缓存的位置添加此行。
COPY marker /dev/null
然后使用
构建
date > marker && docker build .
另一种选择是删除要重建的缓存中间图像。
在构建输出中找到您希望重建的中间图像的哈希值:
Step 27/42 : RUN lolarun.sh
---> Using cache
---> 328dfe03e436
然后删除该图像:
$ docker image rmi 328dfe03e436
或者,如果它给您一个错误,您可以强制执行它:
$ docker image rmi -f 328dfe03e436
最后,重新运行您的构建命令,它需要从那一点重新启动,因为它不在缓存中。
由于没有正式的方法可以做到这一点,最简单的方法是临时更改特定的 运行 命令以包含一些无害的东西,例如 echo:
RUN echo && apt-get -qq update && \
apt-get install nano
构建后删除它。
我有以下 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
我该怎么做? 删除缓存的图像是唯一的选择吗? 是否有任何其他参数可以做到这一点?
一个解决方法:
- 找到您要执行的步骤。
- 在该步骤之前放置一个简单的虚拟操作,如 "RUN pwd"
然后只需构建您的 Dockerfile。它将从缓存中获取该步骤之前的所有内容,然后执行虚拟命令之后的行。
您可以在不使用缓存的情况下重建整个内容,方法是
docker build --no-cache -t user/image-name
要强制从特定行开始重新运行,您可以传递一个未使用的 arg。 Docker 将 ARG 值作为环境变量传递给您的 运行 命令,因此更改 ARG 是对打破缓存的命令的更改。甚至没有必要在 运行 行上自己定义它。
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 .
要在每次构建时更改参数,您可以将时间戳作为参数传递:
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"]
如果将 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
要完成 Dmitry 的回答,您可以使用像 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
...
更简单的技术。
Dockerfile:
在您希望开始跳过缓存的位置添加此行。
COPY marker /dev/null
然后使用
构建date > marker && docker build .
另一种选择是删除要重建的缓存中间图像。
在构建输出中找到您希望重建的中间图像的哈希值:
Step 27/42 : RUN lolarun.sh
---> Using cache
---> 328dfe03e436
然后删除该图像:
$ docker image rmi 328dfe03e436
或者,如果它给您一个错误,您可以强制执行它:
$ docker image rmi -f 328dfe03e436
最后,重新运行您的构建命令,它需要从那一点重新启动,因为它不在缓存中。
由于没有正式的方法可以做到这一点,最简单的方法是临时更改特定的 运行 命令以包含一些无害的东西,例如 echo:
RUN echo && apt-get -qq update && \
apt-get install nano
构建后删除它。