web-dev-qa-db-ja.com

Dockerのjenkinsパイプラインでnpmインストールが失敗する

私はJenkinsパイプラインに関するチュートリアルに従っています。ノード6.10のdocker containerで「hello world」を動作させることができます。

しかし、デフォルトのEmberJSアプリ(ember initを使用)をレポに追加し、それをパイプラインでビルドしようとすると、npm installを実行すると失敗します(ディレクトリアクセスの問題のため)。 Jenkinsfileはここにあります: 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.

注:npm installをルート/ Sudoとしてnot実行したいと思います。

更新:私は次のようにいくつかの進歩を遂げることができました:

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(実際には不可解なジェンキンスワークスペースパス)であり、ユーザーIDは501(グループID 20)などです。ユーザーには名前がありません(これは明らかにこの質問に関係のない他のものを壊している)。

  1. Dockefileを使用するようにエージェントを変更しました:

    agent {
      dockerfile {
        filename 'Dockerfile'
        args '-v /.cache/ -v /.bower/  -v /.config/configstore/'
      }
    }
    
  2. Npm install/bowerが必要とするディレクトリのボリュームを作成するには、args '-v ...'を指定します。

31
les2

から 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
    }
}
22
arturh

環境を追加し、ホームを「。」に設定しますこれを以下のように解決します。

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"
            }
        }
    }
}
21
Dinuka De Silva

この問題で1日を無駄にした後、Pipeline Editorを使用してエージェント段階で環境変数として次を追加するだけで問題が解決することがわかりました。

'npm_config_cache=npm-cache'
15
Swagrid

少しだけ詳細を提供したかった、要するに受け入れられた答えは機能しますが、私はDockerが初めてであり、より良い理解を得たいと思い、見つけたものを共有したいと思いました。

したがって、ジェンキンスのセットアップでは、

docker run -t -d -u 995:315 -w /folder/forProject -v /folder/forProject:/folder/forProject:rw,z ...

その結果、このコンテナはユーザーuid=995 gid=315 groups=315

私が使用していた画像(circleci/node:latest)にはこのUID/GIDを持つユーザーがいないため、ユーザーには「ホーム」フォルダーがなく、マウントされたボリュームに対する権限のみがあります。

NPMコマンドが呼び出されると、そのユーザーのホームディレクトリ(キャッシュ用)を使用しようとします。そのユーザーはイメージ上に作成されていないため、ホームディレクトリは/(Linuxのデフォルト?)。したがって、NPMを正しく機能させるには、ユーザーのコンテナーのHOME環境変数をJenkinsファイル経由で現在のフォルダーにポイントするだけです。

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

したがって、ユーザーに必要な.npmフォルダー/folder/forProject/.npm

うまくいけば、これは誰かに役立ち、あなたが私が間違った何かを見たら私に知らせてください:D

3
JeffBeltran

同じ問題を追加します。 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"
        }
    }
}
3
Pierre

Jenkinsがdockerコンテナを実行するユーザーをオーバーライドできます。たとえば、ここではルート(userid:groupidは0:0)でオーバーライドします。

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

コンソール出力のdocker runパラメーターで現在のユーザーを見つけることができます。

2
Ievgen Goichuk

この設定は私のために機能します。

pipeline {
    agent {
        docker {
            image 'node:6-Alpine'
            args '-p 3000:3000 -p 5000:5000'
            args '-u 0:0'

        }
    }
    environment {
        CI = 'true'
    }
    stages {
        stage('Build') {
            steps {
                sh 'npm install --unsafe-perm'
            }
        }
        stage('Test') {
            steps {
                sh './jenkins/scripts/test.sh'
            }
        }
        stage('Deliver for development') {
            when {
                branch 'development' 
            }
            steps {
                sh './jenkins/scripts/deliver-for-development.sh'
                input message: 'Finished using the web site? (Click "Proceed" to continue)'
                sh './jenkins/scripts/kill.sh'
            }
        }
        stage('Deploy for production') {
            when {
                branch 'production'  
            }
            steps {
                sh './jenkins/scripts/deploy-for-production.sh'
                input message: 'Finished using the web site? (Click "Proceed" to continue)'
                sh './jenkins/scripts/kill.sh'
            }
        }
    }
}
1
yasin lachini

私の場合、問題はコンテナ内でrootではなくユーザーjenkinsだったことです。コンテナ内にwhoamiを設定してそこにたどり着きましたが、cannot determine user 111(たまたまジェンキンです)。だから私は次のことをしました:

stage('Run build') {
        webappImage.inside("-u root") {
            sh "yarn run build"
        }
    }
1
Remigiusz

コンテナ内のユーザーとJenkinsノードを実行しているユーザーのUIDが異なるという同じ問題がありました。コンテナ内のユーザーのUID + GIDを変更(およびユーザーのホームディレクトリの所有権を変更)した後、ビルドノードnpmを実行しているユーザーと一致するようになりました。

これは、container-userのHome-Directoryが書き込み可能でない場合にも発生する可能性があります。

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がビルドノードに一致するように自動的に設定されます。ただし、ホームディレクトリには元の所有者が残ります。

これで、node_modulesは現在のディレクトリに配置されます。

1
user2859193

グローバルな依存関係として設定することなく、ビルド前にnvmNVM_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
0
Bertrand Martel