webentwicklung-frage-antwort-db.com.de

die Installation von npm schlägt in der Jenkins-Pipeline im Andockfenster fehl

Ich verfolge ein Tutorial über die Jenkins-Pipeline und ich kann eine "Hallo Welt" unter dem Knoten 6.10 Docker-Container erhalten.

Wenn ich dem Repo jedoch eine Standard-EmberJS-App (mit ember init) hinzufügte und versuche, diese in der Pipeline zu erstellen, schlägt die Ausführung von npm install fehl (aufgrund von Problemen beim Verzeichniszugriff). Das Jenkinsfile kann hier eingesehen werden: https://github.com/CloudTrap/pipeline-tutorial/blob/fix-build/Jenkinsfile

Die Fehlermeldung, die vom Build ausgegeben wird, ist (die lokal installiert ist und mit Java -jar jenkins.war auf einem Macbook ausgeführt wird, nicht relevant, aber nur für den Fall enthalten):

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.

Hinweis: Ich möchte nichtnpm install als root/Sudo ausführen.

UPDATE: Ich konnte folgende Fortschritte erzielen:

Ich habe den Befehl gefunden, den Jenkins mithilfe des Containers aus den Protokollen erstellt:

[Pipeline] withDockerContainer
$ docker run -t -d -u 501:20 -w /long-workspace-directory -v /long-workspace-directory:/long-workspace-directory:rw -v /[email protected]:/[email protected]:rw -e

Wenn das Docker-Image ausgeführt wird, ist das Arbeitsverzeichnis ein /long-workspace-directory (es ist wirklich ein kryptisch aussehender Pfad für den Jenkins-Arbeitsbereich), und die Benutzer-ID lautet 501 (Gruppennummer 20) usw. Der Benutzer hat keinen Namen (der anscheinend bricht andere Dinge, die nicht mit dieser Frage zusammenhängen).

  1. Agent geändert, um ein Dockefile zu verwenden:

    agent {
      dockerfile {
        filename 'Dockerfile'
        args '-v /.cache/ -v /.bower/  -v /.config/configstore/'
      }
    }
    
  2. Geben Sie args '-v ...' zum Erstellen von Volumes für die Verzeichnisse an, die von npm install/bower benötigt werden.

22
les2

aus 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
    }
}
16
arturh

Nachdem ich einen ganzen Tag mit diesem Problem verschwendet hatte, stellte ich fest, dass das Folgende als Umgebungsvariable in der Agentenphase hinzugefügt wurde.

'npm_config_cache=npm-cache'
12
Swagrid

Hinzufügen der Umgebungen und Festlegen der Startseite auf '.' löst dies wie folgt.

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

Ich füge das gleiche Problem hinzu. Ich habe es mit dem Benutzer root gelöst, um das Docker-Image auszuführen:

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"
        }
    }
}
4
Pierre

diese Konfiguration funktioniert bei mir.

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

In meinem Fall bestand das Problem darin, dass ich innerhalb des Containers Benutzer jenkins anstelle von root war. Ich bin dort durch Setzen von whoami in den Container gekommen und habe eine Fehlermeldung wie cannot determine user 111 (was zufällig jenkins ist) erhalten. Also habe ich folgendes gemacht:

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

Wollte nur ein bisschen mehr Detail bieten, kurz gesagt, die akzeptierte Antwort funktioniert, aber ich bin neu bei Docker und wollte ein besseres Verständnis bekommen und meinte, ich würde mitteilen, was ich gefunden habe. 

Für unser Jenkins-Setup werden also Container über gestartet 

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

Als Ergebnis wird dieser Container als Benutzer uid=995 gid=315 groups=315 ausgeführt.

Da das von mir verwendete Bild (circleci/node: latest) über keinen Benutzer mit dieser UID/GID verfügt, verfügt der Benutzer nicht über einen "Home" -Ordner und hat nur die Berechtigung für das bereitgestellte Volume. 

Wenn NPM-Befehle aufgerufen werden, wird versucht, das Basisverzeichnis dieses Benutzers (für Cache) zu verwenden. Da dieser Benutzer nicht für das Image erstellt wurde, wird das Basisverzeichnis auf / (Standardeinstellung für Linux?) Gesetzt. Damit NPM korrekt funktioniert, weisen wir die HOME-Umgebungsvariable der Container für den Benutzer über die Jenkins-Datei auf den aktuellen Ordner

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

Dadurch kann der Benutzer den erforderlichen .npm-Ordner in /folder/forProject/.npm erstellen.

Hoffentlich hilft dies jemandem, und wenn Sie etwas sehen, was ich falsch verstanden habe, lassen Sie es mich wissen: D

1
JeffBeltran

Wir hatten das gleiche Problem, der Kern des Problems bestand für uns darin, dass der Benutzer im Container und der Benutzer, der den Jenkins-Knoten ausführte, unterschiedliche UIDs hatten. Nach dem Ändern der UID + GID des Benutzers im Container (und Ändern) Eigentümer des Home-Verzeichnisses der Benutzer) Der Benutzer, der den Buildknoten npm ausführt, würde sich normal verhalten.

Dies kann auch passieren, wenn das Home-Verzeichnis des Container-Benutzers nicht beschreibbar ist.

Code in der 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>

Da der Arbeitsbereich in den Container eingebunden ist, gehört er bereits zur UID. Beim Ausführen des Containers durch die Jenkins-Datei werden die UID und die GID von Des Containerbenutzers automatisch so eingestellt, dass sie mit dem Buildnode übereinstimmen. Das Heimatverzeichnis hat jedoch weiterhin seinen ursprünglichen Besitzer.

Nun werden die node_modules im aktuellen Verzeichnis abgelegt.

1
user2859193

Sie können den Benutzer, mit dem Jenkins den Docker-Container ausführt, überschreiben. Hier überschreibe ich beispielsweise das Stammverzeichnis (Benutzer-ID: Groupid ist 0: 0):

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

Sie können den aktuellen Benutzer in den docker run-Parametern in der Konsolenausgabe erkennen.

1
Ievgen Goichuk

Sie können nvm im laufenden Betrieb vor der Erstellung in einem lokalen Verzeichnis mit NVM_DIR installieren, ohne es als globale Abhängigkeit festzulegen:

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

Die neuen Standorte sind:

$ 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