Reputation: 2219
I am trying to build a very simple declarative Jenkinsfile
that is based on the latest node
docker image. I want to install the dependencies for the Node.js
app by calling sh 'npm install ...'
in the Jenkinsfile
. Installing with npm
from the Docker container without Jenkins works like a charm, but not when using Jenkins Pipeline.
Jenkinsfile
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
}
}
}
}
Console Log in 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"
I assume it has to do something with the privileges in the mounted volume from Jenkins and/or the user with which the Docker container ist started from:
args '-u root'
in the Docker code block in the Jenkinsfile. This works but I doubt this is how this should be solved.
docker {
image 'node:latest'
args '-u root'
}
sudo chown -R 1962192188:58041779 "/.npm"
as proposed in the error message. But this leads to:
+ 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
Define a layer RUN npm install axios
in the Dockerfile
. This works, but out of curiosity I want to know why I cannot invoke this directly in Jenkinsfile instead.
FROM node:latest
RUN npm i axios
Upvotes: 4
Views: 4358
Reputation: 1479
This worked for me after trying so many things. It seems Jenkins will map the workspace directory to the docker container.
pipeline {
agent { dockerfile true }
environment {
HOME = "${env.WORKSPACE}"
}
...
Upvotes: 0
Reputation: 2219
The best way to solve this issue is by using one of the following methods (inspired by npm install fails in jenkins pipeline in docker). All three will end up changing the default directory of .npm
(i.e., npm's cache) to the current working directory (which is the Jenkins Job's workspace mapped to the Docker container).
Declarative Pipeline
pipeline {
agent { docker { image 'node:latest'' } }
environment {
HOME = '.'
}
...
Scripted Pipeline
docker.image('node:latest').inside {
withEnv([
'HOME=.',
])
...
--cache
to change the location of the .npm
folder when calling npm install
npm install --cache npm_cache <optional:packagename>
npm_config_cache
used by npm before calling npm install
Declarative Pipeline
pipeline {
agent { docker { image 'node:latest'' } }
environment {
npm_config_cache = 'npm-cache'
}
...
Scripted Pipeline
docker.image('node:latest').inside {
withEnv([
'npm_config_cache=npm-cache',
])
...
Upvotes: 16