最终Dockerfile
#syntax=docker/dockerfile:1.2
FROM maven:3.8.6-openjdk-8-slim as MAVEN_BUILD
COPY . /build/
WORKDIR /build/
RUN --mount=type=cache,target=/root/.m2,id=maven-cache \
mvn clean package -Dmaven.test.skip=true --quiet
FROM openjdk:8-jdk-alpine
COPY --from=MAVEN_BUILD /build/target/*.jar /data/app.jar
WORKDIR /data/
EXPOSE 80
ENV TZ=Asia/Shanghai
ENTRYPOINT ["java","-Xmx512m","-jar","app.jar"]
构建命令
DOCKER_BUILDKIT=1 docker build -t myapp .
RUN --mount=type=cache,target=/root/.m2,id=maven-cache
挂载缓存目录必须在RUN里面执行,后面直接跟构建命令。
DOCKER_BUILDKIT=1 临时使用buildkit方式构建。(不须要修改docker配置文件)
注意这里建议设定 id 参数,因为不提供 id 参数的话,id 的默认值为 target 的值,这样一旦我们以后想修改 taget 路径,就很麻烦。
指定 id 后,target 的路径随意修改扔不会影响结果。
参数 | –mount=type=cache 参数说明 |
id | id 设置一个标志,以便区分缓存。 |
target | (必填项) 缓存的挂载目标文件夹。 |
ro,readonly | 只读,缓存文件夹不能被写入。 |
sharing | 有 sharedprivatelocked 值可供选择。sharing 设置当一个缓存被多次使用时的表现,由于 BuildKit 支持并行构建,当多个步骤使用同一缓存时(同一 id)会发生冲突。shared 表示多个步骤可以同时读写,private 表示当多个步骤使用同一缓存时,每个步骤使用不同的缓存,locked 表示当一个步骤完成释放缓存后,后一个步骤才能继续使用该缓存。 |
from | 缓存来源(构建阶段),不填写时为空文件夹。 |
source | 来源的文件夹路径。 |
验证缓存
Dockerfile
[root@saas /]# cat Dockerfile
#syntax=docker/dockerfile:1.2
FROM busybox:1.36.0
RUN --mount=type=cache,target=/cache,id=cache \
echo cache >> /cache/logs.txt && cat /cache/logs.txt
第一次执行
[root@saas /]# DOCKER_BUILDKIT=1 docker build --progress=plain -t myapp .
#2 [internal] load .dockerignore
#2 transferring context: 2B done
#2 DONE 0.0s
#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 194B done
#1 DONE 0.0s
#3 resolve image config for docker.io/docker/dockerfile:1.2
#3 DONE 0.0s
#4 docker-image://docker.io/docker/dockerfile:1.2
#4 CACHED
#5 [internal] load build definition from Dockerfile
#5 transferring dockerfile: 194B done
#5 DONE 0.0s
#6 [internal] load metadata for docker.io/library/busybox:1.36.0
#6 DONE 0.0s
#7 [stage-0 1/2] FROM docker.io/library/busybox:1.36.0
#7 CACHED
#8 [stage-0 2/2] RUN --mount=type=cache,target=/cache,id=cache echo cache...
#8 0.155 cache
#8 DONE 0.2s
#9 exporting to image
#9 exporting layers
#9 exporting layers done
#9 writing image sha256:66935ee5d7dd5f05ea633915ed16fc7a1cb640768e896dcc7b0c4cea4ec3bfd6 done
#9 naming to docker.io/library/myapp done
#9 DONE 0.0s
注意#8 里面有一个0.155 cache 就是咱们写入共享缓存目录内文件的内容。
修改Dockersfile文件。
[root@saas /]# cat Dockerfile
#syntax=docker/dockerfile:1.2
FROM busybox:1.36.0
RUN --mount=type=cache,target=/cache,id=cache \
echo cache1 >> /cache/logs.txt && cat /cache/logs.txt
修改echo内容。再次构建。
[root@saas /]# DOCKER_BUILDKIT=1 docker build --progress=plain -t myapp .
......
#8 [stage-0 3/3] RUN --mount=type=cache,target=/cache,id=cache echo cache...
#8 0.155 cache
#8 0.155 cache1
#8 DONE 0.2s
......
这时#8步骤输出的cache是2行。第2行是第2次构建写入的内容。说明已经使用到刚刚的共享缓存了。
缓存位置和清理缓存
# cache默认会在
/var/lib/docker/overlay2/26位随机字符/diff/
# 使用命令清理
docker builder prune
相关参考资料:
Docker Buildkit(新增 --mount、–security、–network 等特性)
怎么把一个Java应用打包成Docker镜像
为什么 docker build 不显示命令的任何输出?
https://www.likecs.com/ask-675687.html
Docker Hub Build Mounts RUN --mount=…
https://hub.docker.com/r/docker/dockerfile
Docker Docs Garbage collection
https://docs.docker.com/build/cache/garbage-collection/