Gitlab CI使用Jib构建Maven镜像时ng build阶段报EBUSY锁定错误
Gitlab CI流水线Maven构建NFS文件锁报错问题
执行的构建命令
Gitlab CI流水线中用来构建Maven镜像的命令如下:
./mvnw package -Pprod verify -DskipTests jib:build -Djib.to.image=$IMAGE_TAG -Djib.to.auth.username=gitlab-ci-token -Djib.to.auth.password=$CI_BUILD_TOKEN -Dmaven.repo.local=$MAVEN_USER_HOME
报错详情
命令执行时抛出未捕获异常:
An unhandled exception occurred: EBUSY: resource busy or locked, unlink '/builds/PATH/target/node/.nfs000000007cb56ba90067282d'
错误触发点在./mvnw package执行到Angular生产构建的环节,对应日志片段:
[INFO] > ng build --configuration production [INFO] [INFO] An unhandled exception occurred: EBUSY: resource busy or locked, unlink '/builds/sharing/codeability-sharing-platform/target/node/.nfs000000007cb56ba90067282d'
问题现状
报错提示资源繁忙或被锁定,无法删除target/node目录下的NFS临时文件。这类.nfs文件是NFS存储的特有机制:只要还有进程持有文件句柄,删除原文件就会生成这类临时占位文件,此时强制删除就会报EBUSY错误。
目前已试过所有通用的EBUSY类rmdir错误解决方案,但这类方案都是针对本地非流水线场景的,解决不了mvnw执行流程内部触发的这个报错,暂时没找到有效修复方式。
修复方案
按落地优先级从高到低排:
- 优先把node运行目录挪到runner本地磁盘:给Maven命令加参数
-Dfrontend.nodeInstallDirectory=/tmp/ci-node,让frontend-maven-plugin把node的下载、运行路径从NFS挂载的builds目录改到runner本地的/tmp路径,本地磁盘没有NFS的文件锁机制,能彻底规避这类问题。 - 主动杀残留进程释放文件句柄:在Angular构建步骤跑完、Maven开始清理target目录之前,执行
pkill -f "ng build" || true命令终止所有残留的构建进程,确保没有进程还占着target/node下的文件,从根源避免.nfs临时文件生成。 - 跳过构建阶段的自动删目录逻辑:给
ng build命令加--delete-output-path=false参数,关掉Angular构建时自动清理输出目录的逻辑,等整个jib镜像构建流程全跑完,再在CI步骤最后统一执行rm -rf target/做清理,避开Maven执行流程中删文件触发的锁冲突。
内容的提问来源于stack exchange,提问作者Eduard Frankford
相关产品推荐
相关产品推荐

