Context :
I’m building a react app using a jenkins pipeline, where the agent is docker agent defined by a Dockerfile in the root of my project, the bug happens in the npm ci stage, where i the console prints warnings about the node version being old ( v12 ), which is wierd because i installed the latest using nvm ( see Dockelfile ).
The Problem :
In the build logs it says i’m using node v12, but when building the docker image i printed the node version and it was v20.
This is my Jenkinsfile
:
pipeline {
agent {
dockerfile {
filename 'Dockerfile.agent'
}
}
environment {
TAG="$env.BRANCH_NAME-v$BUILD_NUMBER"
REGISTRY="foo"
AWS_REGION="eu-north-1"
}
stages {
stage('Build React App') {
steps {
script {
sh "npm ci"
sh "npm run build"
}
}
}
stage("Build Docker Image") {
steps {
sh "docker build -t staff-manager-admin-ui ."
}
}
stage('Push to Registry') {
steps {
script {
withCredentials([string(credentialsId: 'aws-key', variable: 'awsKey'), string(credentialsId: 'aws-secret', variable: 'awsSecret')]) {
withEnv(["AWS_ACCESS_KEY_ID=$awsKey", "AWS_SECRET_ACCESS_KEY=$awsSecret", "AWS_DEFAULT_REGION=$AWS_REGION"]) {
sh "aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $REGISTRY"
sh "docker tag staff-manager-admin-ui $REGISTRY:$TAG"
sh "docker push $REGISTRY:$TAG"
}
}
}
}
}
}
}
this is the Dockerfile.agent
:
FROM jenkins/agent:latest
USER root
# Install stuff needed for
RUN apt-get update &&
apt-get install -y npm docker awscli default-jdk &&
rm -rf /var/lib/apt/lists/*
# install npm & node
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
&& . ~/.nvm/nvm.sh
&& nvm install node
&& node -e "console.log('Running Node.js ' + process.version)"
# Add nvm path to bashrc and source it
RUN echo 'export NVM_DIR="$HOME/.nvm"' >> $HOME/.bashrc
&& echo '[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"' >> $HOME/.bashrc
# Source bashrc to make nvm available in this shell
RUN . $HOME/.bashrc
# Add the commands to fix npm permissions
RUN mkdir -p /.npm
RUN chown -R 1002:1002 /.npm
# USER jenkins
USER 1002:1002
Here’s a screenshot of the relevant part of the Docker image building
and then during npm ci
it says i’m using v12 ?
More context :
Repo : https://github.com/HL-Abdallah/staff-manager-admin-ui-cloudsec/tree/acceptation
Full job log :
Started by user Abdallah
20:42:02 Connecting to https://api.github.com using github-access
Obtained Jenkinsfile from 58cd4b60dcc9413beca260ed4c601098ab04d2eb
[Pipeline] Start of Pipeline
[Pipeline] node
Running on gp-agent in /home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Declarative: Checkout SCM)
[Pipeline] checkout
The recommended git tool is: NONE
using credential github-access
Fetching changes from the remote Git repository
Fetching without tags
Checking out Revision 58cd4b60dcc9413beca260ed4c601098ab04d2eb (acceptation)
Commit message: "switch to node form --lts"
> git rev-parse --resolve-git-dir /home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation/.git # timeout=10
> git config remote.origin.url https://github.com/HL-Abdallah/staff-manager-admin-ui-cloudsec.git # timeout=10
Fetching upstream changes from https://github.com/HL-Abdallah/staff-manager-admin-ui-cloudsec.git
> git --version # timeout=10
> git --version # 'git version 2.40.1'
using GIT_ASKPASS to set credentials
> git fetch --no-tags --force --progress -- https://github.com/HL-Abdallah/staff-manager-admin-ui-cloudsec.git +refs/heads/acceptation:refs/remotes/origin/acceptation # timeout=10
> git config core.sparsecheckout # timeout=10
> git checkout -f 58cd4b60dcc9413beca260ed4c601098ab04d2eb # timeout=10
> git rev-list --no-walk 5fa8c7de33f5f562f88479983a05899d360ec4eb # timeout=10
[Pipeline] }
[Pipeline] // stage
[Pipeline] withEnv
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Declarative: Agent Setup)
[Pipeline] isUnix
[Pipeline] readFile
[Pipeline] sh
+ docker build -t d89fb2028932cbbd1bd5b845c31cdbc6219edd4c -f Dockerfile.agent .
Sending build context to Docker daemon 500.1MB
Step 1/9 : FROM jenkins/agent:latest
---> 7ae825327b31
Step 2/9 : USER root
---> Using cache
---> e4b66e958c34
Step 3/9 : RUN apt-get update && apt-get install -y npm docker awscli default-jdk && rm -rf /var/lib/apt/lists/*
---> Using cache
---> a8ee6e6ff6de
Step 4/9 : RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash && . ~/.nvm/nvm.sh && nvm install node && node -e "console.log('Running Node.js ' + process.version)"
---> Running in 4d7be2cfef8e
[91m [0m[91m % Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent [0m[91mL[0m[91me[0m[91mf[0m[91mt[0m[91m Speed
0 0 0 [0m[91m [0m[91m0[0m[91m 0 0 0 0 --:--:-- --:--:[0m[91m-- --:--:-- 0[0m[91m
100 15916 100 15916 0 0 98857 0 --:--:-- --:--:-- --:--:-- 98857
[0m=> Downloading nvm from git to '/root/.nvm'
=> [91mCloning into '/root/.nvm'...
[0m* (HEAD detached at FETCH_HEAD)
master
=> Compressing and cleaning up git repository
=> Appending nvm source string to /root/.bashrc
=> Appending bash_completion source string to /root/.bashrc
=> Close and reopen your terminal to start using nvm or run the following to use it now:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && . "$NVM_DIR/bash_completion" # This loads nvm bash_completion
Downloading and installing node v20.6.1...
[91mDownloading https://nodejs.org/dist/v20.6.1/node-v20.6.1-linux-x64.tar.xz...
[0m[91m
####################################[0m[91m 50.7%[0m[91m
##########[0m[91m###[0m[91m#[0m[91m##[0m[91m#[0m[91m#[0m[91m#[0m[91m#[0m[91m#[0m[91m################################################### [0m[91m100.0%
[0m[91mComputing checksum with sha256sum
[0m[91mChecksums matched!
[0mNow using node v20.6.1 (npm v9.8.1)
Creating default alias: default -> node (-> v20.6.1 *)
Running Node.js v20.6.1
Removing intermediate container 4d7be2cfef8e
---> 79b3a1d0adc5
Step 5/9 : RUN echo 'export NVM_DIR="$HOME/.nvm"' >> $HOME/.bashrc && echo '[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"' >> $HOME/.bashrc
---> Running in d5c5907ade58
Removing intermediate container d5c5907ade58
---> 95c5e8081970
Step 6/9 : RUN . $HOME/.bashrc
---> Running in d3a90d73d2d4
nvm
Removing intermediate container d3a90d73d2d4
---> af3c6dc532dd
Step 7/9 : RUN mkdir -p /.npm
---> Running in 0fdf60936204
Removing intermediate container 0fdf60936204
---> 57945aa41a9f
Step 8/9 : RUN chown -R 1002:1002 /.npm
---> Running in a0cb6cfe91bf
Removing intermediate container a0cb6cfe91bf
---> 7a63cd0f10b1
Step 9/9 : USER 1002:1002
---> Running in 50723e1eb398
Removing intermediate container 50723e1eb398
---> 4fabe0bf14a4
Successfully built 4fabe0bf14a4
Successfully tagged d89fb2028932cbbd1bd5b845c31cdbc6219edd4c:latest
[Pipeline] }
[Pipeline] // stage
[Pipeline] isUnix
[Pipeline] withEnv
[Pipeline] {
[Pipeline] sh
+ docker inspect -f . d89fb2028932cbbd1bd5b845c31cdbc6219edd4c
.
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] withDockerContainer
gp-agent does not seem to be running inside a container
$ docker run -t -d -u 1002:1002 -w /home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation -v /home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation:/home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation:rw,z -v /home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation@tmp:/home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation@tmp:rw,z -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** d89fb2028932cbbd1bd5b845c31cdbc6219edd4c cat
$ docker top 12defe4dd2ae7e0342482472c54957b43a2411e7d25cb517180fbd789eba55ea -eo pid,comm
[Pipeline] {
[Pipeline] withEnv
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Build React App)
[Pipeline] script
[Pipeline] {
[Pipeline] sh
+ npm ci
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: '@csstools/[email protected]',
npm WARN EBADENGINE required: { node: '^14 || >=16' },
npm WARN EBADENGINE current: { node: 'v12.22.12', npm: '7.5.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: '@faker-js/[email protected]',
npm WARN EBADENGINE required: { node: '^14.17.0 || ^16.13.0 || >=18.0.0', npm: '>=6.14.13' },
npm WARN EBADENGINE current: { node: 'v12.22.12', npm: '7.5.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: '@mui/[email protected]',
npm WARN EBADENGINE required: { node: '>=14.0.0' },
npm WARN EBADENGINE current: { node: 'v12.22.12', npm: '7.5.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: '@mui/[email protected]',
npm WARN EBADENGINE required: { node: '>=14.0.0' },
npm WARN EBADENGINE current: { node: 'v12.22.12', npm: '7.5.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: '@remix-run/[email protected]',
npm WARN EBADENGINE required: { node: '>=14' },
npm WARN EBADENGINE current: { node: 'v12.22.12', npm: '7.5.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: '[email protected]',
npm WARN EBADENGINE required: { node: '>=14.0.0' },
npm WARN EBADENGINE current: { node: 'v12.22.12', npm: '7.5.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: '[email protected]',
npm WARN EBADENGINE required: { node: '>=14.0.0' },
npm WARN EBADENGINE current: { node: 'v12.22.12', npm: '7.5.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: '[email protected]',
npm WARN EBADENGINE required: { node: '>= 14' },
npm WARN EBADENGINE current: { node: 'v12.22.12', npm: '7.5.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: '[email protected]',
npm WARN EBADENGINE required: { node: '>=14' },
npm WARN EBADENGINE current: { node: 'v12.22.12', npm: '7.5.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: '[email protected]',
npm WARN EBADENGINE required: { node: '>=14' },
npm WARN EBADENGINE current: { node: 'v12.22.12', npm: '7.5.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: '[email protected]',
npm WARN EBADENGINE required: { node: '>=14' },
npm WARN EBADENGINE current: { node: 'v12.22.12', npm: '7.5.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: '[email protected]',
npm WARN EBADENGINE required: { node: '>=14' },
npm WARN EBADENGINE current: { node: 'v12.22.12', npm: '7.5.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: '[email protected]',
npm WARN EBADENGINE required: { node: '>=14.0.0' },
npm WARN EBADENGINE current: { node: 'v12.22.12', npm: '7.5.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: '[email protected]',
npm WARN EBADENGINE required: { node: '>=14.0.0' },
npm WARN EBADENGINE current: { node: 'v12.22.12', npm: '7.5.2' }
npm WARN EBADENGINE }
npm WARN deprecated @babel/[email protected]: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-property-in-object instead.
npm WARN deprecated [email protected]: This SVGO version is no longer supported. Upgrade to v2.x.x.
npm WARN deprecated @material-ui/[email protected]: Material UI v4 doesn't receive active development since September 2021. See the guide https://mui.com/material-ui/migration/migration-v4/ to upgrade to v5.
npm WARN deprecated @material-ui/[email protected]: Material UI v4 doesn't receive active development since September 2021. See the guide https://mui.com/material-ui/migration/migration-v4/ to upgrade to v5.
added 2135 packages in 2m
257 packages are looking for funding
run `npm fund` for details
[Pipeline] sh
+ npm run build
> [email protected] build
> react-scripts build
internal/modules/cjs/loader.js:818
throw err;
^
Error: Cannot find module 'tapable'
Require stack:
- /home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation/node_modules/enhanced-resolve/lib/Resolver.js
- /home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation/node_modules/enhanced-resolve/lib/ResolverFactory.js
- /home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation/node_modules/enhanced-resolve/lib/index.js
- /home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation/node_modules/webpack/lib/CacheFacade.js
- /home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation/node_modules/webpack/lib/Compilation.js
- /home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation/node_modules/webpack/lib/NormalModule.js
- /home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation/node_modules/webpack-manifest-plugin/dist/index.js
- /home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation/node_modules/react-scripts/config/webpack.config.js
- /home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation/node_modules/react-scripts/scripts/build.js
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:815:15)
at Function.Module._load (internal/modules/cjs/loader.js:667:27)
at Module.require (internal/modules/cjs/loader.js:887:19)
at require (internal/modules/cjs/helpers.js:74:18)
at Object.<anonymous> (/home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation/node_modules/enhanced-resolve/lib/Resolver.js:8:60)
at Module._compile (internal/modules/cjs/loader.js:999:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Module.require (internal/modules/cjs/loader.js:887:19) {
code: 'MODULE_NOT_FOUND',
requireStack: [
'/home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation/node_modules/enhanced-resolve/lib/Resolver.js',
'/home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation/node_modules/enhanced-resolve/lib/ResolverFactory.js',
'/home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation/node_modules/enhanced-resolve/lib/index.js',
'/home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation/node_modules/webpack/lib/CacheFacade.js',
'/home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation/node_modules/webpack/lib/Compilation.js',
'/home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation/node_modules/webpack/lib/NormalModule.js',
'/home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation/node_modules/webpack-manifest-plugin/dist/index.js',
'/home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation/node_modules/react-scripts/config/webpack.config.js',
'/home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation/node_modules/react-scripts/scripts/build.js'
]
}
npm ERR! code 1
npm ERR! path /home/jenkins_khaled/jenkins/workspace/Admin_Frontend_React_acceptation
npm ERR! command failed
npm ERR! command sh -c react-scripts build
npm ERR! A complete log of this run can be found in:
npm ERR! /.npm/_logs/2023-09-09T20_46_34_033Z-debug.log
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Build Docker Image)
Stage "Build Docker Image" skipped due to earlier failure(s)
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Push to Registry)
Stage "Push to Registry" skipped due to earlier failure(s)
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
$ docker stop --time=1 12defe4dd2ae7e0342482472c54957b43a2411e7d25cb517180fbd789eba55ea
$ docker rm -f --volumes 12defe4dd2ae7e0342482472c54957b43a2411e7d25cb517180fbd789eba55ea
[Pipeline] // withDockerContainer
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
ERROR: script returned exit code 1
GitHub has been notified of this commit’s build result
Finished: FAILURE
2
Answers
Fixed by applying these changes to the Dockerfile.agent
When you have multiple
RUN
commands in yourDockerfile
, each of them is run in an independent process. So anything set in the environment of oneRUN
command is not persisted in the environment of nextRUN
command.This is actually required because
nvm
sets theNODE_VERSION
in the environment variable to determine the default version to use.There are a couple of ways to solve this:
You can use a node version specific base image for your
Dockerfile
. That way, you wont even neednvm
. Check out some of the images here: https://hub.docker.com/_/node/ (eg:20-bullseye-slim
)You can use the
ENV
command to persist the environment variables thatnvm
uses, likeNVM_DIR
,NODE_PATH
,NODE_VERSION
andPATH
.