Jenkinsfile位于子目录时为何出现权限问题需root运行?
Jenkins子目录Jenkinsfile触发npm权限错误的解决方法
问题背景
当Jenkinsfile位于项目根目录时流水线执行正常,但放在子目录(如src/demo-dir/Jenkinsfile)时,npm install会返回EACCES权限拒绝错误,无法创建日志或访问缓存目录,提示缓存文件夹包含root所属文件,仅子目录场景出现该问题,root身份运行可验证为权限问题。
错误信息
Error: npm verb cli /usr/bin/node /usr/bin/npm npm info using npm@10.2.4 npm info using node@v20.11.1 npm verb title npm install npm verb argv "install" "--loglevel" "verbose" npm verb logfile logs-max:10 dir:/var/lib/jenkins/workspace/qa-gryph-load-test-prod/.npm/_logs/2024-04-09T00_03_00_112Z- npm verb logfile could not be created: Error: EACCES: permission denied, open '/var/lib/jenkins/workspace/qa-gryph-load-test-prod/.npm/_logs/2024-04-09T00_03_00_112Z-debug-0.log' npm verb logfile no logfile created npm verb stack Error: EACCES: permission denied, open '/var/lib/jenkins/workspace/qa-gryph-load-test-prod/.npm/_cacache/tmp/ab3ad9ff' npm verb cwd /var/lib/jenkins/workspace/qa-gryph-load-test-prod npm verb Linux 4.9.0-13-amd64 npm verb node v20.11.1 npm verb npm v10.2.4 npm ERR! code EACCES npm ERR! syscall open npm ERR! path /var/lib/jenkins/workspace/qa-gryph-load-test-prod/.npm/_cacache/tmp/ab3ad9ff npm ERR! errno -13 npm verb Error: EACCES: permission denied, open '/var/lib/jenkins/workspace/qa-gryph-load-test-prod/.npm/_cacache/tmp/ab3ad9ff' npm ERR! npm ERR! Your cache folder contains root-owned files, due to a bug in npm ERR! previous versions of npm which has since been addressed. npm ERR! npm ERR! To permanently fix this problem, please run: npm ERR! sudo chown -R 109:114 "/var/lib/jenkins/workspace/qa-gryph-load-test-prod/.npm" npm verb exit -13 npm verb unfinished npm timer command:install 1712620980480 npm verb unfinished npm timer reify 1712620980483 npm verb unfinished npm timer reify:loadTrees 1712620980526 npm verb unfinished npm timer idealTree 1712620980527 npm verb unfinished npm timer idealTree:buildDeps 1712620980856 npm verb unfinished npm timer idealTree:#root 1712620980856 npm verb code -13 npm ERR! Log files were not written due to an error writing to the directory: /var/lib/jenkins/workspace/qa-gryph-load-test-prod/.npm/_logs npm ERR! You can rerun the command with `--loglevel=verbose` to see the logs in your terminal script returned exit code 243
示例流水线脚本
pipeline { agent { docker { image 'mcr.microsoft.com/playwright:v1.42.0-focal' args "-v /etc/passwd:/etc/passwd" } } parameters { /* * NODE_ENV = Indicates which properties file to run. */ string(name: 'NODE_ENV', defaultValue: 'prod', description: 'environment to target') booleanParam(name: 'RUN_ARTILLERY_REPORT', defaultValue: false, description: 'key for reporting') } environment { HOME = '.' JENKINS_RUN = 'true' } stages { stage('Checkout SCM') { steps { checkout scm } } stage('Dependencies') { steps { sh 'npm install --loglevel verbose' } } stage('Load Test') { steps { sh """ npx artillery run -e ${params.NODE_ENV} 'src/load-test/load-test.yml' --record --key xxxxxxxxxxxxx """ } } } post { always { archiveArtifacts artifacts: 'src/load-test/report.json' // Optional: Archive report } } }
解决方法
1. 修复现有缓存目录权限
在Dependencies阶段前添加权限修复命令,修正workspace中.npm目录的所属用户:
stage('Fix Permission') { steps { sh 'if [ -d ".npm" ]; then sudo chown -R $(id -u):$(id -g) .npm; fi' } }
2. 指定npm缓存到子目录
修改流水线环境变量,让npm将缓存目录放在Jenkinsfile所在的子目录下,避免权限冲突:
environment { HOME = '.' JENKINS_RUN = 'true' NPM_CONFIG_CACHE = "./src/demo-dir/.npm-cache" }
或直接在npm install命令中指定缓存路径:
sh 'npm install --loglevel verbose --cache ./src/demo-dir/.npm-cache'
3. 切换流水线工作目录到Jenkinsfile所在子目录
将后续操作切换到子目录执行,确保所有文件以当前用户权限创建:
stage('Dependencies') { steps { dir('src/demo-dir') { sh 'npm install --loglevel verbose' } } } stage('Load Test') { steps { dir('src/demo-dir') { sh """ npx artillery run -e ${params.NODE_ENV} '../load-test/load-test.yml' --record --key xxxxxxxxxxxxx """ } } }
4. 容器内明确以当前用户运行
在Docker agent的args中添加用户指定参数,确保容器内以Jenkins运行用户身份执行命令:
agent { docker { image 'mcr.microsoft.com/playwright:v1.42.0-focal' args "-v /etc/passwd:/etc/passwd -u \$(id -u):\$(id -g)" } }
内容的提问来源于stack exchange,提问作者Belief Gratini
相关产品推荐
相关产品推荐

