web-dev-qa-db-fra.com

reconstruire l'image docker à partir d'une étape spécifique

J'ai le Dockerfile ci-dessous.

FROM ubuntu:14.04
MAINTAINER Samuel Alexander <[email protected]>

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"]

Lors de la création de l'image, elle a échoué à l'étape 23, c'est-à-dire.

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

Maintenant, quand je reconstruis, il commence à se construire à partir de l'étape 23 car Docker utilise le cache.

Mais si je veux reconstruire l'image de l'étape 21, c'est-à-dire.

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

Comment puis je faire ça? La suppression de l'image en cache est-elle la seule option? Y a-t-il un paramètre supplémentaire pour le faire?

41
sag

Vous pouvez reconstruire le tout sans utiliser le cache en faisant un

docker build --no-cache -t user/image-name

Pour forcer une réexécution à partir d'une ligne spécifique, vous pouvez passer un argument qui est autrement inutilisé. Docker transmet les valeurs ARG en tant que variables d'environnement à votre commande RUN, donc la modification d'un ARG est une modification de la commande qui rompt le cache. Il n'est même pas nécessaire de le définir vous-même sur la ligne RUN.

FROM ubuntu:14.04
MAINTAINER Samuel Alexander <[email protected]>

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"]

Et puis lancez-le avec un argument unique:

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

Pour changer l'argument avec chaque build, vous pouvez passer un horodatage comme arg:

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

ou:

docker build --build-arg INCUBATOR_VER=$(date +%s) -t user/image-name .

En passant, je recommanderais les modifications suivantes pour garder vos couches plus petites, plus vous pourrez fusionner les étapes de nettoyage et de suppression sur une seule commande RUN après le téléchargement et l'installation, plus votre image finale sera petite . Sinon, vos couches comprendront toutes les étapes intermédiaires entre le téléchargement et le nettoyage:

FROM ubuntu:14.04
MAINTAINER Samuel Alexander <[email protected]>

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"]
39
BMitch

Une solution:

  1. Recherchez l'étape à partir de laquelle vous souhaitez exécuter.
  2. Avant cette étape, mettez une opération factice simple comme "RUN pwd"

Ensuite, créez simplement votre Dockerfile. Il prendra tout jusqu'à cette étape du cache, puis exécutera les lignes après la commande factice.

37
user6461348

Pour compléter la réponse de Dmitry, vous pouvez utiliser uniq arg comme date +%s pour garder toujours la même ligne de communication

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

Dockerfile:

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

Une technique plus simple.

Dockerfile:
Ajoutez cette ligne à l'endroit où vous souhaitez que la mise en cache soit ignorée.

COPY marker /dev/null

Puis construisez en utilisant

date > marker && docker build .

5
Bernard

Si place ARG INCUBATOR_VER=unknown en haut, le cache ne sera pas utilisé en cas de changement de INCUBATOR_VER depuis la ligne de commande (vient de tester la construction). Pour moi a travaillé:

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