首页 文章

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

提问于
浏览
18

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

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

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

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.

注意:我不想以root / sudo身份运行 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

因此,当docker镜像运行时,它的工作目录是一个 /long-workspace-directory (它有一个名称(这显然打破了与此问题无关的其他事情) .

  • 更改了代理以使用Dockefile:
agent {
  dockerfile {
    filename 'Dockerfile'
    args '-v /.cache/ -v /.bower/  -v /.config/configstore/'
  }
}
  • 指定 args '-v ...' 用于为npm install / bower需要的目录创建卷 .

7 回答

  • 0

    来自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
        }
    }
    
  • 1

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

    'npm_config_cache=npm-cache'
    
  • 4

    我添加了同样的问题 . 我使用 root 用户解决了它以运行Docker镜像:

    node {
        stage("Prepare environment") {
            checkout scm
            // Build the Docker image from the Dockerfile located at the root of the project
            docker.build("${JOB_NAME}")
        }
    
        stage("Install dependencies") {
            // Run the container as `root` user
            // Note: you can run any official Docker image here
            withDockerContainer(args: "-u root", image: "${JOB_NAME}") {
                sh "npm install"
            }
        }
    }
    
  • 13

    添加环境并将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"
                }
            }
        }
    }
    
  • 2

    我们遇到了同样的问题,问题的核心是,Container中的用户和运行Jenkins节点的用户有不同的UID . 在更改容器中用户的UID GID(并更改用户主目录的所有权)以匹配运行构建节点的用户之后,npm将表现正常 .

    如果容器用户的主目录不可写,也可能发生这种情况 .

    Dockerfile中的代码:

    RUN usermod -u <uid of buildnode> <container user> && \
        groupmod -g <gid of buildnode> <container user group> && \
        chown -R <container user>:<container user group> /home/<container user>
    

    当工作区安装到容器中时,它将属于UID . 通过Jenkinsfile运行容器时,容器用户的UID和GID会自动设置为与buildnode匹配 . 但主目录仍将拥有其原始所有者 .

    现在node_modules将放在当前目录中 .

  • 10

    你可以覆盖Jenkins运行docker容器的用户,例如在这里我用root覆盖(userid:groupid是0:0):

    docker { 
        image 'node:8'
        args '-u 0:0'
    }
    

    您可以在控制台输出中的 docker run 参数中找到当前用户 .

  • 1

    您可以在构建之前动态安装 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
    

    新的位置是:

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

相关问题