--mount=type=buildkit 中的缓存

A.R*_*K.S 9 maven docker dockerfile docker-build

我正在尝试从 docker 容器中获取 Maven 离线构建。我已经启用了 buildkit。我已经运行mvn dependency:go-offline -s ~/checkouts/settings.xml以缓存/root/.m2主机的依赖项。我希望在构建 maven 项目的容器中使用它。

这是我的 Dockerfile:

#syntax=docker/dockerfile:experimental
FROM maven:3.6.1-jdk-11 AS build
WORKDIR /
COPY . /
RUN --mount=type=cache,target=/root/.m2 mvn -o install 

FROM scratch
COPY --from=build /admin/admin- 
rest/target/admin-rest.war /webapps/ROOT.war
Run Code Online (Sandbox Code Playgroud)

当我尝试使用docker build此 Dockerfile 时,出现以下错误:

插件 org.codehaus.mojo:build-helper-maven-plugin:3.0.0 或其依赖项之一无法解析:无法在离线模式下访问中心 ( https://repo.maven.apache.org/maven2 ) 和工件 org.codehaus.mojo:build-helper-maven-plugin:jar:3.0.0 之前没有从它下载。-> [帮助 1]

我的 Docker 版本:

Client:
 Version:           18.09.6
 API version:       1.39
 Go version:        go1.10.8
 Git commit:        481bc77
 Built:             Sat May  4 02:35:57 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.1
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.5
  Git commit:       74b1e89
  Built:            Thu Jul 25 21:19:41 2019
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.2.5
  GitCommit:        bb71b10fd8f58240ca47fbb579b9d1028eea7c84
 runc:
  Version:          1.0.0-rc6+dev
  GitCommit:        2b18fe1d885ee5083ef9f0838fee39b62d653e30
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683
Run Code Online (Sandbox Code Playgroud)

我是否正确地期望/root/.m2我的主机需要安装到/root/.m2docker 容器环境内部?当我运行时,mvn -o install它需要引用已安装的/root/.m2?

我添加了tail -f /dev/null,删除了第二个构建阶段,并在缓存安装指令不变的情况下更改了mvn installtomvn version以进行调试。我看到没有任何东西安装到容器内的 /root/.m2 上。它是空的。(不确定这是否是调试它的正确方法,因为在构建映像后它可能会被卸载)

BMi*_*tch 18

最好将其--mount=type=cache视为 docker 中的命名卷,由 BuildKit 管理,如果 BuildKit 缓存已满或请求修剪,则可能会被删除。下次运行构建时,相同命名的卷可能可用,从而显着减少下载依赖项所花费的构建时间。虽然非常有用,但这似乎不是您在此处寻找的内容。要使用这样的缓存,您需要go-offline在 Dockerfile 中包含更早的步骤:

#syntax=docker/dockerfile:experimental
FROM maven:3.6.1-jdk-11 AS build
WORKDIR /
# copy just the pom.xml for cache efficiency
COPY ./pom.xml /
# go-offline using the pom.xml
RUN --mount=type=cache,target=/root/.m2 mvn dependency:go-offline
# now copy the rest of the code and run an offline build
COPY . /
RUN --mount=type=cache,target=/root/.m2 mvn -o install 

FROM scratch
COPY --from=build /admin/admin-rest/target/admin-rest.war /webapps/ROOT.war
Run Code Online (Sandbox Code Playgroud)

要将目录从主机挂载到容器中,您似乎正在寻找的是绑定挂载。使用 BuildKit 的实验设置,它是可用的,但仅适用于构建上下文,而不适用于构建主机上的任何任意目录。为此,您可以将.m2目录放在构建上下文目录中,然后在 Dockerfile 中使用以下行:

RUN --mount=type=bind,source=./.m2,target=/root/.m2,rw mvn -o install
Run Code Online (Sandbox Code Playgroud)

请注意,如果任何依赖项发生更改,则 Maven 可能会再次尝试通过网络进行连接。

  • 关于从主机挂载目录的注释不正确, `--mount=type=bind,source=./.m2,target=/root/.m2,rw` 从上下文或另一个容器挂载目录,取决于“from=”参数。不幸的是,它不支持从主机挂载。 (2认同)
  • @Evgeny 答案指定“但仅限于构建上下文,而不是构建主机上的任何任意目录”。我尽力指出了OP要求安装任意主机目录的限制,并解释了为什么他们的命令不起作用。 (2认同)
  • 这里重要的部分是 **每个** `mvn` 语句必须包含 ` --mount=type=cache,target=/root/.m2` 挂载。否则将重新下载依赖项。 (2认同)