假设我决定进行以下多阶段构建:
FROM node:8.6-alpine AS build1
#some other commands
FROM node:8.5-alpine AS build2
# yet another commands
在build1和build2之间肯定有一些相同的层。码头工人会复制图层,还是以某种方式附加引用已构建的图层?
答案 0 :(得分:1)
接下来是在新机器上构建dockerfile的结果:
# docker build -t test:1 .
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM node:8.6-alpine AS build1
8.6-alpine: Pulling from library/node
88286f41530e: Pull complete
d0e8a23136b3: Pull complete
5ad5b12a980e: Pull complete
Digest: sha256:60cd58a7a2bd9fec161f53f8886e451f92db06b91f4f72d9188eeea040d195eb
Status: Downloaded newer image for node:8.6-alpine
---> b7e15c83cdaf
Step 2/2 : FROM node:8.5-alpine AS build2
8.5-alpine: Pulling from library/node
88286f41530e: Already exists
aa0be12c5610: Pull complete
719d346e6de2: Pull complete
Digest: sha256:945cf56668d3e58a3b045291564963ccde29a68da9c1483e19d8a0b06749db06
Status: Downloaded newer image for node:8.5-alpine
---> 7a779c246a41
Successfully built 7a779c246a41
Successfully tagged test:1
从输出中,您可以看到图像ID 88286f41530e
被重新用作Already exists
。
和docker images
输出:
REPOSITORY TAG IMAGE ID CREATED SIZE
node 8.6-alpine b7e15c83cdaf 13 months ago 67.2MB
node 8.5-alpine 7a779c246a41 14 months ago 67MB
因此,多重构建中第一阶段的基础映像也保留在缓存中。
从这个post:
通常,从Docker v1.10开始,图像和图层不再是同义词。 取而代之的是,映像直接引用一层或多层,这些层最终构成派生容器的文件系统。
因此,当某些图像被重用时,这些图层肯定会被重用。
当然,这取决于您在multibuild中使用的基础映像,它们需要重用。
无论如何,我认为与传统构建相比,multibuild只是增加了一些技巧,但是层重用机制是相同的。
答案 1 :(得分:1)
我相信可以使用普通的docker build
层缓存,但是还有其他更好的答案。
FROM ubuntu:18.04 AS first
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \
apt-get install -y --no-install-recommends \
python3
RUN echo first
FROM ubuntu:18.04 AS second
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \
apt-get install -y --no-install-recommends \
python3
RUN echo second
规则是,您必须从相同的基本镜像开始(在您的示例中没有共享),并且必须重复相同的精确命令(或COPY 完全相同的文件内容);一旦您偏离此路径,就不会共享任何内容,包括以后的所有相同命令。
您可以use the AS alias in later FROM directives,因此,如果您确实要共享某个基础层,最好进行显式地操作
FROM ubuntu:18.04 AS base
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \
apt-get install -y --no-install-recommends \
python3
FROM base AS first
RUN echo first
FROM base AS second
RUN echo second
在多阶段构建中更常见的情况是,它具有非常不同的“构建”和“运行时”映像,因此这通常不适用。
FROM golang:1.11 AS build
WORKDIR /go/src/github.com/me/myapp
COPY ./ ./
RUN go install .
FROM alpine
COPY --from=build /go/bin/myapp /usr/bin
CMD ["myapp"]