Jenkins:在Docker代理中使用“sh npm i ...”无法正常工作

4

意图

我尝试构建一个非常简单的基于最新的node Docker镜像的声明式Jenkinsfile。我想通过在Jenkinsfile中调用sh 'npm install ...'来安装Node.js应用程序的依赖项。从Docker容器中使用npm进行安装在Jenkins之外表现良好,但在使用Jenkins Pipeline时出现问题。

Jenkinsfile

pipeline {
   agent { 
       docker {
           image 'node:latest'
       }
   }
   stages {
      stage('Install Dependencies') {
         steps {
            sh 'npm -v' // sanity check
            sh 'ls -lart' // debugging filesystem
            sh 'npm i axios' // this leads to the error
         }
      }
   }
}

Jenkins中的控制台日志

+ npm install axios
npm ERR! code EACCES
npm ERR! syscall mkdir
npm ERR! path /.npm
npm ERR! errno -13
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 1962192188:58041779 "/.npm"

我猜想这与Jenkins挂载卷的权限和/或以Docker容器启动的用户有关:

我尝试过的方法

  1. args '-u root' in the Docker code block in the Jenkinsfile. This works but I doubt this is how this should be solved.

    docker {
        image 'node:latest'
        args '-u root'
    }
    
  2. sudo chown -R 1962192188:58041779 "/.npm" as proposed in the error message. But this leads to:

    + sudo chown -R 1962192188:58041779 /.npm
    /Users/<user>/.jenkins/workspace/pipe@tmp/durable-664f481d/script.sh: 1: 
    /Users/<user>/.jenkins/workspace/pipe@tmp/durable-664f481d/script.sh: sudo: not found
    
  3. Define a layer RUN npm install axios in the Dockerfile. This works, but out of curiosity I want to know why I cannot invoke this directly in Jenkinsfile instead.

    FROM node:latest
    
    RUN npm i axios
    

这篇帖子解决了我的问题:https://dev59.com/C1gQ5IYBdhLWcg3wcjos - Christopher Graf
2个回答

15

解决此问题的最佳方法之一是使用以下方法之一(受到npm在Jenkins管道中在Docker中失败启发)。 这三个方法最终都会将 .npm (即npm的缓存)的默认目录更改为当前工作目录(这是映射到Docker容器的Jenkins作业工作区)。

将环境变量HOME设置为当前的工作目录

声明性管道

pipeline {
    agent { docker { image 'node:latest'' } }
    environment {
        HOME = '.'
    }
    ...

脚本化流水线

docker.image('node:latest').inside {
    withEnv([
        'HOME=.',
    ])
    ...

使用额外参数--cache,在调用npm install时更改.npm文件夹的位置。

npm install --cache npm_cache <optional:packagename>

在调用npm install之前设置由npm使用的环境变量npm_config_cache

声明性Pipeline

pipeline {
    agent { docker { image 'node:latest'' } }
    environment {
        npm_config_cache = 'npm-cache'
    }
    ...

脚本化流水线

docker.image('node:latest').inside {
    withEnv([
        'npm_config_cache=npm-cache',
    ])
    ...

0

在尝试了很多方法后,这个对我有用。看起来Jenkins会将工作空间目录映射到Docker容器中。

pipeline {
    agent { dockerfile true }
    environment {
        HOME = "${env.WORKSPACE}"
    }
...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接