Copy output of npm install to docker container - node.js

I dockerized node.js and all works fine
Dockerfile:
FROM node:alpine
WORKDIR '/app'
COPY package.json .
RUN npm install
COPY . .
EXPOSE 9000
CMD ["npm", "run", "dev"]
I'm trying to run npm install outside Dockerfile and to copy content of npm install to docker container
On docker host i ran
npm install --prefix /opt/npm/ -g
Folder /opt/npm/lib/node_modules/ui is created. In that folder there are bunch json files and folder node_modules.Dockerfile is in that foler.Now, in Dockerfile i skipped npm install and just copied content of /opt/npm/lib/node_modules/ui to docker container.
Modified Dockerfile
FROM node:alpine
WORKDIR '/app'
COPY . .
EXPOSE 9000
Built image from Dockerfile sucessfully, but when trying to run container from that image
docker run -p 9000:4200 pm
> ui#0.0.0 dev /app
> ng serve --host 0.0.0.0 --proxy-config src/proxy.conf.json
sh: ng: not found
npm ERR! code ELIFECYCLE
npm ERR! syscall spawn
npm ERR! file sh
npm ERR! errno ENOENT
npm ERR! ui#0.0.0 dev: `ng serve --host 0.0.0.0 --proxy-config src/proxy.conf.json`
npm ERR! spawn ENOENT
npm ERR!
npm ERR! Failed at the ui#0.0.0 dev script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm WARN Local package.json exists, but node_modules missing, did you mean to install?
Is it possible to run npm install outside docker container ?

When dockerizing any application you should always compile and install dependencies in the docker container.
Your Docker file start form node:alpine. this means that when you install an npm package that needs compilation outside (your OS) the alpine OS won't be able to use this.
Best practice is to always build your application on the same OS. That's way docker introduce build container.
# Dockerfile
FROM node:12.13-alpine As build
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --only=production
FROM node:12.13-alpine as production
WORKDIR /usr/src/app
COPY ./ ./ # copy static files
COPY --from=build /usr/src/app/node_modules ./. # Copy node_modules from build container
EXPOSE 3000
CMD ["node", "main.js"]
# .dockerignore
node_modules
Dockerfile
Try to fit this to your environment

Related

Whenever performing docker build, always get dependency error

When ever I perform docker build I get this:
Sending build context to Docker daemon 263.5MB
Step 1/19 : FROM node:alpine3.16 AS development
---> 789fb8adc830
Step 2/19 : WORKDIR /usr/src/app
---> Using cache
---> 75ce41f126cc
Step 3/19 : COPY --chown=node:node package*.json ./
---> 802474abc3db
Step 4/19 : RUN npm ci
---> Running in 74111097fd82
npm WARN ERESOLVE overriding peer dependency
npm WARN While resolving: ajv-keywords#3.5.2
npm WARN Found: peer ajv#"^6.9.1" from the root project
npm WARN
npm WARN Could not resolve dependency:
npm WARN peer ajv#"^6.9.1" from the root project
npm ERR! code EAI_AGAIN
npm ERR! syscall getaddrinfo
npm ERR! errno EAI_AGAIN
npm ERR! request to https://registry.npmjs.org/ajv failed, reason: getaddrinfo EAI_AGAIN registry.npmjs.org
npm ERR! A complete log of this run can be found in:
npm ERR! /root/.npm/_logs/2022-09-10T08_30_14_350Z-debug-0.log
The command '/bin/sh -c npm ci' returned a non-zero code: 1
this is the docker file used to build the image
FROM node:alpine3.16 AS development
# Create app directory
WORKDIR /usr/src/app
# Copy application dependency manifests to the container image.
# A wildcard is used to ensure copying both package.json AND package-lock.json (when available).
# Copying this first prevents re-running npm install on every code change.
COPY --chown=node:node package*.json ./
# Install app dependencies using the `npm ci` command instead of `npm install`
RUN npm ci
# Bundle app source
COPY --chown=node:node . .
# Use the node user from the image (instead of the root user)
USER node
FROM node:alpine3.16 AS build
WORKDIR /usr/src/app
COPY --chown=node:node package*.json ./
# In order to run `npm run build` we need access to the Nest CLI which is a dev dependency. In the previous development stage we ran `npm ci` which installed all dependencies, so we can copy over the node_modules directory from the development image
COPY --chown=node:node --from=development /usr/src/app/node_modules ./node_modules
COPY --chown=node:node . .
# Run the build command which creates the production bundle
RUN npm run build
# Set NODE_ENV environment variable
ENV NODE_ENV production
# Running `npm ci` removes the existing node_modules directory and passing in --only=production ensures that only the production dependencies are installed. This ensures that the node_modules directory is as optimized as possible
RUN npm ci --only=production --omit=dev && npm cache clean --force
USER node
FROM node:alpine3.16 AS production
# Copy the bundled code from the build stage to the production image
COPY --chown=node:node --from=build /usr/src/app/node_modules ./node_modules
COPY --chown=node:node --from=build /usr/src/app/dist ./dist
# Start the server using the production build
CMD [ "node", "dist/main.js" ]
How can I resolve the issue? this issue never occurs when the service is built and executed in VSCode
Most likely you are encountering this issue: https://github.com/npm/cli/issues/4998.
Using either --force or --legacy-peer-deps option should do the trick for you, for now.

Testing local npm package using Docker

I have a local npm package which I need to build and run npm link inside Docker container. I have these line in my Dockerfile
WORKDIR /usr/src/app
COPY . .
RUN npm ci && npm run build && npm link
How can I test this npm package outside of Docker container ?

package.json not found when moving from Dockerfile to docker-compose

I'm getting to know React and created a small application using Create-React-App, which is run inside a docker container using the following dockerfile:
FROM node:latest
WORKDIR /app
# add `/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:$PATH
# install app dependencies
COPY package.json ./
COPY package-lock.json ./
RUN npm install --silent
RUN npm install -g react-scripts#3.4.1 -g --silent
#add app to container
COPY . ./
CMD ["npm", "start"]
That works fairly well and I now wanted to integrate this into a docker-compose workflow, to run an api backend using asp.net core and this React application side-by-side:
version: '3.7'
services:
backend:
asp.netcore
db:
sql2019linux
ui:
container_name: ui
build:
context: ./UI
dockerfile: Dockerfile
ports:
- '8080:3000'
volumes:
- './:/app'
- '/app/node_modules'
This now fails with the node error:
npm ERR! code ENOENT
npm ERR! syscall open
npm ERR! path /app/package.json
npm ERR! errno -2
npm ERR! enoent ENOENT: no such file or directory, open '/app/package.json'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent
The backend and db services are coming up finde. What exactly is going sideways here and how to I fix it?
I think this may be your problem.
volumes:
- './:/app'
Looks like you are mounting the directory that the docker-compose files is in to the app directory of the container and npm start is probably bawking because it cannot find the package.json in the workdir of the built image (which is also /app).
Try removing the volumes.

npm script is unable to find file in workdir in a docker container

This is my Dockerfile:
FROM node:12
WORKDIR /app
COPY . /app
RUN npm install
EXPOSE 3000
CMD ["npm", "start"]
This is the npm script in my package.json
"start": "main.js $npm_config_e $npm_config_t"
when I run the docker image I get this error
sh: 1: main.js: not found
npm ERR! code ELIFECYCLE
npm ERR! syscall spawn
npm ERR! file sh
npm ERR! errno ENOENT
npm ERR! image1#1.0.0 start: `main.js`
However when I do an 'ls' the main.js is in the working directory (/app)
also if I change the Dockerfile to:
CMD ["node", "main.js"]
it works. So why does the npm script not find the main.js file?
Seems obvious now but the solution was to add node to the npm script:
"start": "node main.js $npm_config_e $npm_config_t"

Docker-compose up : no such file or directory, open '/usr/src/app/package.json'

I'm using docker and docker-compose to run my express nodejs api.
Here is my docker file:
FROM node:10-alpine
ARG NODE_ENV=development
ENV NODE_ENV=${NODE_ENV}
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
RUN chmod 755 /usr/src/app
CMD [ "npm", "start" ]
And as I mentioned I'm using docker-compose, here is the docker-compose.yml file content:
version: "3"
services:
service:
build: .
volumes:
- .:/usr/src/app
- /usr/src/app/node_modules
ports:
- 3001:3001
command: npm start
After running docker-compose up, I'm facing an error says it's not able to find package.json.
Here is the error:
service_1 | npm ERR! path /usr/src/app/package.json
service_1 | npm ERR! code ENOENT
service_1 | npm ERR! errno -2 service_1 | npm ERR! syscall open
service_1 | npm ERR! enoent ENOENT: no such file or directory, open '/usr/src/app/package.json'
service_1 | npm ERR! enoent This is related to npm not being able to find a file.
service_1 | npm ERR! enoent
service_1 |
service_1 | npm ERR! A complete log of this run can be found in:
service_1 | npm ERR! /root/.npm/_logs/2019-04-17T07_54_07_773Z-debug.log
xuser-api_service_1 exited with code 254
Please help to find my mistake.
your working directory is /usr/src/app and you copied the package file on root directory .
you have to something like this
# set working directory
WORKDIR /usr/src/app
# install node_modules
ADD package.json /usr/src/app/package.json
RUN npm install
# copy codebase to docker codebase
ADD . /usr/src/app
you may be using an old image which does not contain latest changes.
make sure you using the latest image of your docker file.
docker-compose build
then run
docker-compose up
if you doing frequent changes to Dockerfile for testing then use.
docker-compose up --build
Extend your build section to this:
build:
context: MySuperAngularProject
dockerfile: ./Dockerfile
In context you may set folder with your Angular project with Dockerfile

Resources