I\'m following a tutorial about Jenkins pipeline and I can get a \"hello world\" working under at node 6.10 docker container.
But, when I added a default EmberJS app
Having wasted a whole day on this issue, I found simply adding the following as an environment variable at the agent stage using the Pipeline Editor removed the problem.
'npm_config_cache=npm-cache'
We had the same issue, the core of the problem for us was, that the user in the Container and the User running the Jenkins node had different UIDs. After changing the UID+GID of the user in the container (and changing ownership of the users home-directory) to match the user running the build node npm would behave normal.
This might also happen if the Home-Directory of the container-user is not writeable.
Code in the 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>
As the Workspace is mounted into the container it will already belong to the UID. When running the container through the Jenkinsfile the UID and GID of the container user are set automatically to match the buildnode. But the home directory will still have its original owner.
Now the node_modules will be placed in the current directory.
You can override the user that Jenkins runs the docker container with, for example here I override with the root (userid:groupid is 0:0):
docker {
image 'node:8'
args '-u 0:0'
}
You can spot the current user in the docker run
parameters in the console output.
Wanted to just provide a bit more detail, in short the accepted answer works but that I'm new to Docker and wanted to get a better understanding and figured i'd share what i found.
So for our jenkins setup, it starts containers via
docker run -t -d -u 995:315 -w /folder/forProject -v /folder/forProject:/folder/forProject:rw,z ...
As a result this container is running as user uid=995 gid=315 groups=315
Since the image I was using (circleci/node:latest) doesn’t have a user with this UID/GID, the user will not have a “home” folder and will only have permission on the mounted volume.
When NPM commands are called it will try using that users home directory (for cache) and since that user wasn’t created on the image, the home directory gets set to /
(default for linux?). So to get NPM to work correctly we simply point the containers HOME environment variable for the user to the current folder via the Jenkins file
pipeline {
agent none
stages {
stage('NPM Installs') {
agent {
docker {
image 'circleci/node:latest'
}
}
environment { HOME="." }
...
}
}
}
Thus giving the user the ability to create the required .npm
folder in /folder/forProject/.npm
Hopefully this is helpful to someone and if you see something that i got wrong please let me know :D
When Jenkins runs the stage in Docker agent it usually sets HOME=/
(image WORKDIR
value), but Jenkins user does not have write permissions in this directory, that's why npm
cannot create its cache directory ~/.npm
. To solve this you need either to override HOME
or NPM default cache directory:
environment {
// Override HOME to WORKSPACE
HOME = "${WORKSPACE}"
// or override default cache directory (~/.npm)
NPM_CONFIG_CACHE = "${WORKSPACE}/.npm"
}
this configuration work for me.
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'
}
}
}
}