Docker agent inside Jenkins - npm "cannot find module" - node.js

I'm working on automation of following build steps:
- building frontend application with webpack
- running tests on it
I am using Jenkins with blue-ocean plugin enabled, here is Jenkinsfile:
Jenkinsfile:pipeline {
agent {
dockerfile {
filename 'Dockerfile'
}
}
stages {
stage('Build') {
steps {
sh 'npm run build'
}
}
}
}
I'm using following Dockerfile
FROM node:latest
WORKDIR /app
COPY . /app
RUN npm install webpack -g && npm install
The problem is that when running npm run build it can not find webpack:
> webpack --config webpack-production.config.js --progress --colors
module.js:529
throw err;
^
Error: Cannot find module 'webpack'
at Function.Module._resolveFilename (module.js:527:15)
at Function.Module._load (module.js:476:23)
at Module.require (module.js:568:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (/var/lib/jenkins/workspace/l-ui-webpack-example_master-IXSLD4CQSVAM2DRFHYHOYUANEHJ73R5PUGW4BMYVT5WPGB6ZZKEQ/webpack-production.config.js:1:79)
It looks like commands are being executed in host context, not on container as manual running works just fine:
docker build . -t sample
docker run sample npm run build
Here is full jenkins log:Jenkins build log
Here is a link to a repository: Source code

I had exactly the same issue. For some reason, 'RUN npm install' within the Dockerfile didn't take effect in the Jenkins pipeline although it worked well when I built the image manually.
I got the pipeline working by running "npm install" as a step in the pipeline. So add this to your Jenkinsfile before the 'Build' stage:
stage ('install app') {
steps {
sh "npm install"
}
}
I don't know why this happens but it might have something to do with how Jenkins sets the context for the Docker build. I hope someone else can elaborate on this.

Related

Docker error when running container Error: Cannot find module '/home/app/server.js'

I'm getting the following error and I'm struggling to find the issue
After successfully building my image using the following Dockerfile
Command used
docker build -t my-app:1.0 .
FROM node:13-alpine
# run something in the docker image
RUN mkdir -p /home/app
# this allows you to copy something from the host into docker image
COPY . /home/app
# inside the container it runs the command node server.js
# cmd is an entry point command, whereas run as used later
CMD ["node","/home/app/server.js"]
I have run the following command to run the container
docker run my-app:1.0
it throws the following error:
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
192:docker_compose_demo tech$ docker run my-app:1.0
internal/modules/cjs/loader.js:965
throw err;
^
Error: Cannot find module '/home/app/server.js'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:962:15)
at Function.Module._load (internal/modules/cjs/loader.js:838:27)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47 {
code: 'MODULE_NOT_FOUND',
requireStack: []
}
I changed the path in the Dockerfile and yet is not finding it.
Can someone tell what I'm doing wrong?
The first thing is, to use the WORKDIR instead of running mkdir.
Why use WORKDIR ?
The WORKDIR instruction sets the working directory for any RUN, CMD,
ENTRYPOINT, COPY and ADD instructions that follow it in the
Dockerfile. If the WORKDIR doesn’t exist, it will be created even if
it’s not used in any subsequent Dockerfile instruction
You can refer the below Dockerfile -
FROM node:13-alpine
# Creates directory and sets it as current working directory
WORKDIR /home/app
# Copy everything from local current directory to docker/image current directory
COPY . .
# inside the container it runs the command node server.js
# cmd is an entry point command, whereas run as used later
CMD ["node","server.js"]

Error trying run react Docker image on k8s

I'm building a Micro-services E-commerce project, I need to create a docker image for each server in my project and run them inside K8s cluster. After successfully creating images for all back-end server I tried creating a docker image for my React front-end app, every time I try creating the image this error happened.
Here is my docker configuration:
FROM node:alpine
WORKDIR /src
COPY package*.json ./
RUN npm install --silent
COPY . .
CMD ["npm ","start"];
Here is the error:
Error: Cannot find module '/src/npm '
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
at Function.Module._load (node:internal/modules/cjs/loader:778:27)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:79:12)
at node:internal/main/run_main_module:17:47 {
code: 'MODULE_NOT_FOUND',
requireStack: []
}
Sometimes it throws an error like this:
webpack output is served from content not from webpack is served from content not from webpack is served from /app/public docker
This is a community wiki answer posted for better visibility. Feel free to expand it.
To resolve described issues, steps below need to be done.
Upgrade Dockerfile:
WORKDIR /src
COPY package*.json ./
RUN npm install --silent
COPY . .
CMD ["npm","start"];
Use version 3.4.0 for react-scripts
Add stdin_open: true to docker-compose file

Jenkins - docker: not found

I'm pretty new to do docker and jenkins but wanted to see if I could get a node app automatically deployed and running on my raspberry pi. In an ideal world, I'd like to have Jenkins pull down code from github, use a jenkinsfile and dockerfile to build and run the docker image (hopefully this is possible).
jenkinsfile
pipeline {
agent {
dockerfile true
}
environment {
CI = 'true'
HOME = '.'
}
stages {
stage('Install dependencies') {
steps {
sh 'npm install'
}
}
stage('Test') {
steps {
sh './scripts/test'
}
}
stage('Build Container') {
steps {
sh 'docker build -t test-app:${BUILD_NUMBER} . '
}
}
}
}
dockerfile
# Create image based on the official Node image
FROM node:12
# Create a directory where our app will be placed
RUN mkdir -p /usr/src/app
# Change directory so that our commands run inside this new directory
WORKDIR /usr/src/app
# Copy dependency definitions
COPY package.json /usr/src/app
# Install dependecies
RUN npm install
# Get all the code needed to run the app
COPY . /usr/src/app
# Expose the port the app runs in
EXPOSE 3000
# Serve the app
CMD ["npm", "start"]
However, when I try to run this in jenkins, I get the following error: ../script.sh: docker: not found. This seems to be the case for any docker command. I actually tried running some other command starting with 'sudo' and it complained that sudo: not found. Is there a step missing or am I trying to do something in an incorrect way. (NOTE: docker is installed on the raspberry pi. I can log in with the jenkins user and execute docker commands. It just doesn't work through the web ui) Any advice would be appreciated.
Thanks!
Apparently this section was breaking it:
agent {
dockerfile true
}
When I set this:
agent any
it finished the build, including docker commands without any issues. I guess I just don't understand how that piece works. Any explanations would be helpful!

Failed test is hanging Jenkins pipeline

I am making a pipeline on Jenkins to test and deploy my node.js application using Docker containers. But I am getting my pipeline stuck because a test is failing. The behaviour I would expect is pipeline finishes without executing next stages but it will not get stuck.
Jenkinsfile:
pipeline {
agent any
stages {
stage('Build') {
steps {
sh '''docker build --tag my-web:$BUILD_NUMBER .
docker stop my-web&& docker rm my-web
echo "Build step finished"'''
}
}
stage('Unit test') {
steps {
sh '''docker build -t my-web-test -f Dockerfile.test .
docker run --rm my-web-test
'''
}
}
stage('Run') {
steps {
sh '''docker run --name my-web -p 3000:3000 my-web:$BUILD_NUMBER node /var/www/index.js &
'''
echo 'RUNNING'
}
}
stage('End') {
steps {
echo 'End of pipeline'
}
}
}
}
Dockerfile.test:
FROM node:alpine
RUN mkdir /var/test
WORKDIR /var/test
COPY package.json /var/test/
RUN npm install && npm install -g mocha
COPY src/ /var/test/
CMD ["mocha", "tests/", "--recursive"]
When I trigger the pipeline:
If I remove Unit test stage from pipeline everything works OK and application begins running.
If I do not remove Unit test stage, testing stage begins and I get a result of 14 test passed and 1 failed but the pipeline hangs in this step so Run step never triggers and the pipeline keeps in Running status.
14 passing (2s)
1 failing
1) Checking user first-time-login
Should redirect to change-password page:
Error: expected "Location" of "/dashboard/change-password", got "/dashboard"
at Test._assertHeader (node_modules/supertest/lib/test.js:249:12)
at Test._assertFunction (node_modules/supertest/lib/test.js:283:11)
at Test.assert (node_modules/supertest/lib/test.js:173:18)
at localAssert (node_modules/supertest/lib/test.js:131:12)
at /var/test/node_modules/supertest/lib/test.js:128:5
at Test.Request.callback (node_modules/superagent/lib/node/index.js:728:3)
at IncomingMessage.<anonymous> (node_modules/superagent/lib/node/index.js:916:18)
at endReadableNT (_stream_readable.js:1154:12)
at processTicksAndRejections (internal/process/task_queues.js:77:11)
Newer versions of mocha need to exit, otherwise the server keeps running so next stage is never reached.
mocha --exit

how to fix npm: not found error

This is my first Jenkins pipeline project. I created a simple Node.js application, and I uploaded into hithub (public repo) and all I am trying to do with my Jenkinsfile is to "npm install" in my Build stage. I believe Jenkins is finding the Jenkinsfile but it is just not finding the npm. I am using jenkins official docker image to run my jenkins server. Here are the two plugging that I have installed
1) NodeJS Plugin and 2) Pipeline NPM Integration Plugin
and here is the file
pipeline {
agent any
stages {
stage ("Build") {
steps {
sh "npm install"
}
}
}
}
and this is the error I am getting when I run my 'Build Now'
[second project] Running shell script
+ npm install
/var/jenkins_home/workspace/second project#tmp/durable-ef33ffd4/script.sh: 2: /var/jenkins_home/workspace/second project#tmp/durable-ef33ffd4/script.sh:
npm: not found
can someone help?
I suppose, your npm binary isn't in PATH variable.
Try to specify full path to npm, usually it's /usr/bin
pipeline {
agent any
stages {
stage ("Build") {
steps {
sh "/usr/bin/npm install"
}
}
}
}
You can check npm path in console using command which npm
May be, you already figured this. Have you hosted your machine's docket socket in the container when you started the Jenkins container?
Specifically, you need use -v /var/run/docker.sock:/var/run/docker.sock on your docker run command.
Then in your pipeline, you need to run the npm on a docker container that is built it from official node docker image, such as node:10.11.0-alpine. Here is an example
pipeline {
agent {
docker {
image 'node:10.11.0-alpine'
}
}
stages {
stage ("Build") {
steps {
sh "npm install"
}
}
}
}
If you are on windows than try to run CMD as Administrator and then install NPM it will work for you

Resources