npm安装在docker的jenkins管道中失败

les*_*es2 37 npm jenkins ember.js docker jenkins-pipeline

我正在关注Jenkins管道的教程,我可以在节点6.10 docker容器下找到一个"hello world".

但是,当我向ember initrepo 添加一个默认的EmberJS应用程序(使用)并尝试在管道中构建它时,它在运行npm install时失败(因为目录访问问题).Jenkins文件可以在这里看到:https://github.com/CloudTrap/pipeline-tutorial/blob/fix-build/Jenkinsfile

构建打印的错误消息(在本地安装并java -jar jenkins.war在Macbook上运行,不相关但仅包括在内)是:

npm ERR! Linux 4.9.12-moby
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "install"
npm ERR! node v6.10.0
npm ERR! npm  v3.10.10
npm ERR! path /.npm
npm ERR! code EACCES
npm ERR! errno -13
npm ERR! syscall mkdir

npm ERR! Error: EACCES: permission denied, mkdir '/.npm'
npm ERR!     at Error (native)
npm ERR!  { Error: EACCES: permission denied, mkdir '/.npm'
npm ERR!     at Error (native)
npm ERR!   errno: -13,
npm ERR!   code: 'EACCES',
npm ERR!   syscall: 'mkdir',
npm ERR!   path: '/.npm',
npm ERR!   parent: 'pipeline-tutorial' }
npm ERR! 
npm ERR! Please try running this command again as root/Administrator.
Run Code Online (Sandbox Code Playgroud)

注:我想不会运行npm install为根/须藤.

更新:我已经取得了如下进展:

我找到了Jenkins用来使用日志中的容器构建的命令:

[Pipeline] withDockerContainer
$ docker run -t -d -u 501:20 -w /long-workspace-directory -v /long-workspace-directory:/long-workspace-directory:rw -v /long-workspace-directory@tmp:/long-workspace-directory@tmp:rw -e
Run Code Online (Sandbox Code Playgroud)

因此,当docker镜像运行时,它的工作目录是一个/long-workspace-directory(它真的是一个神秘的jenkins工作空间路径),用户ID是501(组ID 20)等.用户没有名字(这显然打破其他与此问题无关的事情).

  1. 更改代理程序以使用Dockefile:

    agent {
      dockerfile {
        filename 'Dockerfile'
        args '-v /.cache/ -v /.bower/  -v /.config/configstore/'
      }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 指定args '-v ...'为目录npm install/bower需要创建卷.

Din*_*lva 29

添加环境并将Home设置为'.' 解决这个问题如下.

pipeline {
    agent { docker { image 'node:8.12.0' } }
    environment {
        HOME = '.'
    }
    stages {
        stage('Clone') {
            steps {
                git branch: 'master',
                    credentialsId: '121231k3jkj2kjkjk',
                    url: 'https://myserver.com/my-repo.git'
            }
        }
        stage('Build') {
            steps {
                sh "npm install"
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 哇,魔术!这也为我解决了,谢谢。我想npm取决于詹金斯没有设置的`HOME`变量。 (3认同)

art*_*urh 24

来自https://github.com/jenkins-infra/jenkins.io/blob/master/Jenkinsfile

docker.image('openjdk:8').inside {
    /* One Weird Trick(tm) to allow git(1) to clone inside of a
    * container
    */
    withEnv([
        /* Override the npm cache directory to avoid: EACCES: permission denied, mkdir '/.npm' */
        'npm_config_cache=npm-cache',
        /* set home to our current directory because other bower
        * nonsense breaks with HOME=/, e.g.:
        * EACCES: permission denied, mkdir '/.config'
        */
        'HOME=.',
    ]) {
            // your code
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 为了完整性`环境{HOME ="." 修复了Jenkins声明性语法的问题. (9认同)
  • 你只需要设置`HOME = .`,因为`npm_config_cache`是`$ HOME/.npm`,所以在这种情况下它将是`./.npm`而不是`/ .npm` (8认同)
  • 我可以确认只设置 'npm_config_cache=npm-cache' 就足够了 (2认同)

小智 15

在这个问题上浪费了一整天,我发现只需在代理阶段添加以下作为环境变量,使用管道编辑器删除了问题.

'npm_config_cache=npm-cache'
Run Code Online (Sandbox Code Playgroud)

  • 如何使用此配置? (2认同)

Jef*_*ran 8

只想提供更多细节,简而言之,接受的答案有效,但我是 Docker 的新手,想要更好地理解并认为我会分享我的发现。

所以对于我们的 jenkins 设置,它通过以下方式启动容器

docker run -t -d -u 995:315 -w /folder/forProject -v /folder/forProject:/folder/forProject:rw,z ...
Run Code Online (Sandbox Code Playgroud)

结果这个容器以用户身份运行 uid=995 gid=315 groups=315

由于我使用的图像 (circleci/node:latest) 没有具有此 UID/GID 的用户,因此该用户将没有“home”文件夹,并且只有对已安装卷的权限。

当调用 NPM 命令时,它将尝试使用该用户的主目录(用于缓存),并且由于该用户不是在映像上创建的,所以主目录被设置为/ (Linux 的默认值?)。因此,为了让 NPM 正常工作,我们只需通过 Jenkins 文件将用户的容器 HOME 环境变量指向当前文件夹

pipeline {
  agent none
  stages {
    stage('NPM Installs') {
      agent {
        docker {
            image 'circleci/node:latest'
        }
      }
      environment { HOME="." }
      ...
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

从而使用户能够.npm/folder/forProject/.npm

希望这对某人有帮助,如果您发现我做错了什么,请告诉我:D


Ole*_* Sh 7

当 Jenkins 在 Docker 代理中运行阶段时,它通常会设置HOME=/(图像WORKDIR值),但是 Jenkins 用户在此目录中没有写入权限,这就是为什么npm无法创建其缓存目录的原因~/.npm。要解决此问题,您需要覆盖HOME或 NPM 默认缓存目录:

environment {
    // Override HOME to WORKSPACE
    HOME = "${WORKSPACE}"
    // or override default cache directory (~/.npm)
    NPM_CONFIG_CACHE = "${WORKSPACE}/.npm"
}
Run Code Online (Sandbox Code Playgroud)


Ber*_*tel 0

您可以nvm在构建之前在本地目录中即时安装,而NVM_DIR无需将其设置为全局依赖项:

mkdir -p node_dir
export NVM_DIR=$(pwd)/node_dir
curl https://raw.githubusercontent.com/creationix/nvm/v0.33.1/install.sh | bash
source $(pwd)/node_dir/nvm.sh
nvm install 7
nvm use 7
Run Code Online (Sandbox Code Playgroud)

新地点是:

$ which node
~/someDir/node_dir/versions/node/v7.7.2/bin/node

$ which npm
~/someDir/node_dir/versions/node/v7.7.2/bin/npm
Run Code Online (Sandbox Code Playgroud)