GitLab CI/CD构建SpringBoot上传jar报No such file or directory错误
SpringBoot Monorepo GitLab CI/CD 制品找不到问题排查解决
问题现象
搭建SpringBoot单体仓库(monorepo)的GitLab CI/CD流水线时,出现两类关联报错:
- Maven打包阶段执行
ls已确认target目录下存在springboot.jar,但制品上传阶段提示无匹配文件,最终提示无文件可上传,任务状态显示成功但制品未实际上传 - 后续Docker构建阶段提示找不到
springboot.jar,任务执行失败,退出码为1
相关配置与报错日志
Maven打包任务配置
maven-package: stage: package inherit: default: true variables: true script: - cd springboot - mvn clean package -P dev - cd target - ls -al artifacts: when: always paths: - springboot.jar tags: - docker
Maven打包任务执行日志
$ cd target $ ls -al total 41124 drwxr-xr-x 9 root root 4096 Jun 25 11:53 . drwxrwxrwx 5 root root 4096 Jun 25 11:53 .. drwxr-xr-x 4 root root 4096 Jun 25 11:53 classes drwxr-xr-x 3 root root 4096 Jun 25 11:53 generated-sources drwxr-xr-x 3 root root 4096 Jun 25 11:53 generated-test-sources drwxr-xr-x 2 root root 4096 Jun 25 11:53 maven-archiver drwxr-xr-x 3 root root 4096 Jun 25 11:53 maven-status -rw-r--r-- 1 root root 42053990 Jun 25 11:53 springboot.jar -rw-r--r-- 1 root root 13258 Jun 25 11:53 springboot.jar.original drwxr-xr-x 2 root root 4096 Jun 25 11:53 surefire-reports drwxr-xr-x 3 root root 4096 Jun 25 11:53 test-classes Uploading artifacts for successful job 00:01 Uploading artifacts... WARNING: springboot.jar: no matching files. Ensure that the artifact path is relative to the working directory ERROR: No files to upload Cleaning up project directory and file based variables 00:00 Job succeeded
Dockerfile配置
FROM openjdk:latest MAINTAINER vdoma.de VOLUME /tmp ADD target/springboot.jar app.jar ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
Docker构建报错日志
ADD failed: file not found in build context or excluded by .dockerignore: stat target/springboot.jar: file does not exist Cleaning up project directory and file based variables 00:01 ERROR: Job failed: exit code 1
根本原因
两个报错都是相对路径基准认知错误导致的:
- GitLab CI收集制品的路径基准是作业初始工作目录(即仓库克隆后的根目录,对应变量
$CI_PROJECT_DIR),script块里执行cd命令仅对当前shell会话的执行路径生效,不会改变制品收集的路径基准。当前配置里artifacts写的springboot.jar,Runner会去仓库根目录查找该文件,实际文件存放在springboot/target/springboot.jar路径下,自然匹配不到,导致制品上传失败。 - Docker构建的文件查找基准是执行
docker build时指定的上下文目录(默认是执行命令时的当前目录,一般为仓库根目录),Dockerfile里写的target/springboot.jar会从上下文根目录开始查找,和jar实际存放的springboot/target/路径不匹配,就算制品上传成功也会找不到文件。
解决方法
- 修正Maven打包任务的制品路径,配置为相对于仓库根目录的完整路径:
artifacts: when: always paths: - springboot/target/springboot.jar
提示:尽量避免在script块中频繁切换目录,可以直接通过mvn的
-f参数指定pom文件路径,全程保持在仓库根目录执行命令,从根源减少路径错误,示例脚本:mvn -f springboot/pom.xml clean package -P dev ls -al springboot/target
- 修正Docker构建阶段的路径匹配问题,二选一即可:
- 方案1:直接修改Dockerfile中的ADD路径,和jar实际存放路径对齐:
执行docker build时确保上下文为仓库根目录即可。ADD springboot/target/springboot.jar app.jar - 方案2:如果不想修改Dockerfile,在执行docker build前手动创建对应目录并复制jar包到预期路径:
mkdir -p target cp springboot/target/springboot.jar target/ # 再执行原有docker build命令
- 方案1:直接修改Dockerfile中的ADD路径,和jar实际存放路径对齐:
内容的提问来源于stack exchange,提问作者Glory Pierrette
相关产品推荐
相关产品推荐

