Maven已成功解压Nexus Zip到target,Dockerfile为何找不到该目录?
我有一个存放在Nexus仓库中的其他项目的Zip制品,需要在Maven的compile阶段通过当前项目的pom.xml下载该文件,之后通过Docker将其移动到其他目录。
为了解压这个Zip包,我在pom.xml中配置了如下插件:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>3.0.2</version> <executions> <execution> <id>unpack</id> <phase>compile</phase> <goals> <goal>unpack</goal> </goals> </execution> </executions> <configuration> <artifactItems> <artifactItem> <groupId>projectGroupId</groupId> <artifactId>ProjectAtrefact</artifactId> <version>${project.version}-SNAPSHOT</version> <type>zip</type> </artifactItem> </artifactItems> <outputDirectory>${project.build.directory}/deps/dev</outputDirectory> <overWrite>true</overWrite> <stripVersion>true</stripVersion> <excludeTransitive>true</excludeTransitive> <includes>**</includes> </configuration> </plugin>
从Bamboo的构建日志可以看到,Zip文件已经成功下载并解压,Maven阶段执行完成:
[INFO] Downloaded from snapshots: http://repo.xyz.com:8081/nexus/content/groups/libs-snapshot/com/<parent>/<project>/1.0.0-SNAPSHOT/<project>-1.0.0-20220930.103511-22.zip (1.3 MB at 30 MB/s) build 30-Sep-2022 10:41:36 [INFO] Unpacking /mnt/bamboo-ebs/bamboo-agent/artifacts/com/<parent>/<project>/1.0.0-SNAPSHOT/<project>-1.0.0-SNAPSHOT.zip to /mnt/bamboo-ebs/bamboo-agent/build-dir/SHARED-AD1-JOB1/target/deps/dev with includes "*" and excludes ""
按照配置,解压后的文件应该在target/deps/dev目录下,但我在Dockerfile中执行RUN ls -lR target时,系统提示该目录不存在:
#9 [4/6] RUN ls -lR target error 30-Sep-2022 10:42:05 #9 sha256:185ecaf76c80e6942603dec50ea957ddae25e329ceeed2c8b485455b6d3c92e2 error 30-Sep-2022 10:42:05 #9 0.508 ls: cannot access target: No such file or directory error 30-Sep-2022 10:42:05 #9 ERROR: executor failed running [/bin/sh -c ls -lR target]: exit code: 2
请问我哪里操作出错了?能否给出相关建议?
核心原因
Docker构建环境和Bamboo执行Maven的环境是完全隔离的两个文件系统。Bamboo在本地代理机器上执行Maven生成的target目录,并不会自动同步到Docker容器的构建上下文里。
具体修复建议
确认Docker构建上下文范围
Docker构建时只会将指定上下文目录(默认是Dockerfile所在目录)内的文件复制到容器构建环境中。如果Bamboo执行Maven的目录和Docker构建上下文不重叠,target目录根本不会被包含进去。检查你的Docker命令是否指定了正确的上下文,比如执行docker build .时,.就是当前目录,要确保target目录在这个上下文范围内。调整Maven输出目录到Docker上下文内
修改pom.xml中outputDirectory的路径,让解压后的文件直接生成在Docker构建上下文目录下,比如:<outputDirectory>${project.basedir}/docker/deps/dev</outputDirectory>这样在Docker构建时,该目录会被包含到上下文里,容器内就能访问到。
使用多阶段构建传递文件
如果不想修改Maven输出路径,可以用Docker多阶段构建:- 第一阶段使用Maven镜像执行编译和解压操作,生成
target目录; - 第二阶段从第一阶段复制
target目录到最终镜像中。
示例Dockerfile:
# 第一阶段:执行Maven构建 FROM maven:3.8.6-openjdk-11 AS builder WORKDIR /app COPY pom.xml . COPY src ./src RUN mvn compile # 第二阶段:复制产物到最终镜像 FROM your-base-image:tag WORKDIR /app COPY --from=builder /app/target ./target # 后续操作...- 第一阶段使用Maven镜像执行编译和解压操作,生成
检查Bamboo构建步骤顺序
确保Bamboo中先执行Maven编译步骤,再执行Docker构建步骤,并且两个步骤使用相同的工作目录,避免Maven生成的target目录被清理或不在Docker上下文里。
内容的提问来源于stack exchange,提问作者ajayv

