詹金斯:“sh npm i ...”在 docker 代理中不起作用

Chr*_*raf 1 node.js npm jenkins docker npm-install

意图

我正在尝试构建一个Jenkinsfile基于最新nodedocker 镜像的非常简单的声明。我想安装的依赖Node.js通过调用应用程序sh 'npm install ...'Jenkinsfilenpm在没有 Jenkins 的情况下从 Docker 容器安装 with很有魅力,但在使用 Jenkins Pipeline 时则不然。

詹金斯档案

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
         }
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

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"
Run Code Online (Sandbox Code Playgroud)

我认为它必须对来自 Jenkins 和/或启动 Docker 容器的用户的挂载卷中的权限执行某些操作:

我试过的

  1. args '-u root'在 Jenkinsfile 的 Docker 代码块中。这有效,但我怀疑这应该如何解决。

    docker {
        image 'node:latest'
        args '-u root'
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. sudo chown -R 1962192188:58041779 "/.npm"正如错误消息中所建议的那样。但这导致:

    + 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
    
    Run Code Online (Sandbox Code Playgroud)
  3. 限定层RUN npm install axiosDockerfile。这有效,但出于好奇,我想知道为什么我不能直接在 Jenkinsfile 中调用它。

    FROM node:latest
    
    RUN npm i axios
    
    Run Code Online (Sandbox Code Playgroud)

Chr*_*raf 9

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

将 ENV 变量 HOME 设置为当前工作目录

声明式管道

pipeline {
    agent { docker { image 'node:latest'' } }
    environment {
        HOME = '.'
    }
    ...
Run Code Online (Sandbox Code Playgroud)

脚本管道

docker.image('node:latest').inside {
    withEnv([
        'HOME=.',
    ])
    ...
Run Code Online (Sandbox Code Playgroud)

调用时使用附加参数--cache更改.npm文件夹的位置npm install

npm install --cache npm_cache <optional:packagename>
Run Code Online (Sandbox Code Playgroud)

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

声明式管道

pipeline {
    agent { docker { image 'node:latest'' } }
    environment {
        npm_config_cache = 'npm-cache'
    }
    ...
Run Code Online (Sandbox Code Playgroud)

脚本管道

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