Node.js error in docker - node.js

I using node:latest image.
And get
ModuleBuildError: Module build failed: ModuleBuildError: Module build failed: Error: spawn /hobover_web_client/node_modules/pngquant-bin/vendor/pngquant ENOENT.
Dockerfile
FROM node:latest
# set working directory
RUN mkdir -p /hobover_web_client
WORKDIR /hobover_web_client
ENV NPM_CONFIG_LOGLEVEL=warn
COPY package.json yarn.lock /hobover_web_client/
# install app dependencies
RUN rm -rf node_modules/ && yarn install --ignore-scripts && yarn global add babel babel-cli webpack nodemon pngquant optipng recjpeg
ADD . /hobover_web_client
In docker-compose.yml
version: '2'
hobover_web_client:
container_name: hobover_web_client
build: ./hobover_web_client
command: yarn start
ports:
- "8080:8080"
volumes:
- ./hobover_web_client:/hobover_web_client
- /hobover_web_client/node_modules
Build work successfully, but up cause an error.
How can I fix it if without docker it works?

Your issue the is mount of app and node_modules in the same directory. When you use below in docker-compose
- ./hobover_web_client:/hobover_web_client
You are overshadowing the existing node_modules. So you need to use NODE_PATH to relocate your packages. Change your Dockerfile to below
FROM node:latest
# set working directory
RUN mkdir -p /hobover_web_client /node_modules
WORKDIR /hobover_web_client
ENV NPM_CONFIG_LOGLEVEL=warn NODE_PATH=/node_moudles
COPY package.json yarn.lock /hobover_web_client/
# install app dependencies
RUN yarn install --ignore-scripts && yarn global add babel babel-cli webpack nodemon pngquant optipng recjpeg
ADD . /hobover_web_client
Change your compose to below
version: '2'
hobover_web_client:
container_name: hobover_web_client
build: ./hobover_web_client
command: yarn start
ports:
- "8080:8080"
volumes:
- ./hobover_web_client:/hobover_web_client
- /node_modules
So now your /node_modules goes to a anonymous volume, which you as such don't need and can remove, because the path is inside different folder

Related

Dockerizing NodeJS – keeping node modules

I have an NodeJS express app that I want to dockerize. For that I created a Dockerfile:
FROM node:18 AS server
ENV NODE_ENV=production
WORKDIR /app
COPY package*.json /
RUN npm ci
COPY . .
I also have a .dockerignore file:
node_modules/
client/node_modules/
Dockerfile
docker-compose.yml
.git
.gitignore
.dockerignore
.env
All is run with a help of docker-compose.yml:
version: '3.8'
services:
app:
container_name: my-app
image: my-org/my-app
build:
context: .
dockerfile: Dockerfile
command: node index.js
ports:
- "3030:3030"
environment:
HELLO: world
env_file:
- .env
When I run the Dockerfile commands in this order, the COPY . . seems to remove the node_modules from the image, that are created with npm ci that runs beforehand. I've tried it with first running COPY . . and then npm ci and node_modules stays in the image.
My question is – is it better to run npm ci before COPY . ., and if the answer is yes, then how can I make the node_modules stay?
I had a similar problem and used for that a "build container".
You ignored the node_modules folder in your .dockerignore. Therfore it does not get copied in your image.
# The instructions for the first stage
FROM node:16-alpine as builder
ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}
RUN apk --no-cache add python3 make g++
COPY ./package*.json ./
RUN npm install
# ------------------------------------
# The instructions for second stage
FROM node:16-alpine
WORKDIR /opt/OpenHaus/backend
COPY --from=builder node_modules node_modules
RUN apk --no-cache add openssl
COPY . ./
#COPY ./package.json ./
#ENV HTTP_PORT=8080
ENV NODE_ENV=production
#ENV DB_HOST=10.0.0.1
#EXPOSE 8080
CMD ["node", "index.js"]
With that the dependencies are "build" and copied from the build container inside your node.js image.
More to read:
https://medium.com/#kahana.hagai/docker-compose-with-node-js-and-mongodb-dbdadab5ce0a
https://dev.to/alex_barashkov/using-docker-for-nodejs-in-development-and-production-3cgp

docker-compose volume started acting weird, no permissions on files after switching branches

We have been using docker-compose for 1 year and we had no problems. in the past week we each started getting a weird error related to permissions
at internal/main/run_main_module.js:17:47 : Error: EPERM: operation not permitted, open <PATH TO FILE>
only happens when I switch branches
compose structure:
version: "2.4"
# template:
x-base: &base-service-template
env_file:
- ./.env
working_dir: /app/
volumes:
- ./src:/app/src:cached
services:
service1:
image: service1
<<: *base-service-template
service2:
image: service2
<<: *base-service-template
we are all working on OSX. we tried giving docker permissions over the filesystem and it still didn't work.
BUT there is something that works. restarting the daemon. but i don't want to restart the daemon each time I switch branches
additional info:
the docker file base of each service looks like this
FROM node:12-alpine as builder
ENV TZ=Europe/London
RUN npm i npm#latest -g
RUN mkdir /app && chown node:node /app
WORKDIR /app
RUN apk add --no-cache python3 make g++ tini \
&& apk add --update tzdata
USER node
COPY package*.json ./
RUN npm install --no-optional && npm cache clean --force
ENV PATH /app/node_modules/.bin:$PATH
COPY . .
FROM builder as dev
USER node
CMD ["nodemon", "src/services/service/service.js"]
FROM builder as prod
USER node
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["node", "src/services/service/service.js"]
I run on the dev layer so that we can leverage the nodemon code reload.
docker version: Docker version 19.03.13, build 4484c46d9d
docker-compose version: docker-compose version 1.27.4, build 40524192
So after trying some weird stuff, an answer i found was:
after doing this:
remember to restart the shell that you run your compose from.
An edit from the future: it still misbehaves sometimes so this may not fix for everyone

Access node modules in typescript while using docker & docker compose

I'm trying to create a docker image that is hosting a NodeJS project during develop. It simply executes the NodeJS application with nodemon so it restarts every time when I make changes.
I also use TypeScript to develop the application. TypeScript must have access to a installed #types module. However the mounted volume that should show the node_modules folder is empty. So TypeScript cannot find the modules and cannot compile. My IDE is also complaining (obviously)
Is there a way to make the node_modules visible for TypeScript?
This is my Dockerfile:
FROM node:alpine
# Create app directory
WORKDIR /usr/src/app
# Install app dependencies
COPY package.json .
RUN npm install
# Bundle app source
COPY . .
# Run app
CMD [ "npm", "start" ]
This is my docker-compose.yml:
version: "3"
services:
server:
build: .
environment:
- NODE_ENV=development
command: npm run debug
volumes:
- .:/usr/src/app
- /usr/src/app/node_modules
ports:
- "8080:8080"
- "9229:9229"
You should use a separate folder for your node_modules and then set that folder in NODE_PATH environment
FROM node:alpine
# Create app directory
ENV NODE_PATH /usr/node_modules
WORKDIR /usr/node_modules
# Install app dependencies
COPY package.json .
RUN npm install
WORKDIR /usr/src/app
# Bundle app source
COPY . .
# Run app
CMD [ "npm", "start" ]
This way your code would be separate and the node_modules will there in image itself. Anytime you add a new module you will rebuild the image, else development can go fine withe mounted volume

New package.json packages are not showing in Docker container

I am using Docker with Docker Compose and these are my files:
#DOCKERFILE
FROM mhart/alpine-node
# Create app directory
RUN mkdir -p /home/app
# Bundle app soure
COPY . /home/app
# From now on we work in /home/app
WORKDIR /home/app
# Install yarn and node modules
RUN echo -e 'http://dl-cdn.alpinelinux.org/alpine/edge/main\nhttp://dl-
cdn.alpinelinux.org/alpine/edge/community\nhttp://dl-
cdn.alpinelinux.org/alpine/edge/testing' > /etc/apk/repositories \
&& apk add --no-cache yarn \
&& yarn
EXPOSE 8080
This is the docker-compose file for dev:
app:
build: .
command: yarn start:dev
environment:
NODE_ENV: development
ports:
- '8080:8080'
volumes:
- .:/home/app
- /home/app/node_modules
The problem I am having is that this setup seems to work just once because no matter which new module I add to the package.json, whenever I run docker-compose build it will not install the new package.
The reason why I am using the volumes is because nodemon would not work without .:/home/app, but if the node modules are not installed in the host then it will fail, reason why I need /home/app/node_modules. I suspect this could be the cause of my error, but I am not sure how to circumvent that.
I solved this by moving my src code inside an src directory.
This means my docker-compose.yml file now looks like this:
app:
build: .
command: yarn start:dev
environment:
NODE_ENV: development
ports:
- '8080:8080'
volumes:
- ./src:/home/app/src
Since I am not mounting the whole dir with the node_modules, new ones seem to be installed correctly.
The package.json should be copied into app directory and "npm install" should be invoked in Dockerfile before copying the bundle line.
#DOCKERFILE
FROM mhart/alpine-node
# Create app directory
RUN mkdir -p /home/app
WORKDIR /home/app
# Install app dependencies
COPY package.json /home/app
RUN npm install
# Bundle app soure
COPY . /home/app
# Install yarn and node modules
RUN echo -e 'http://dl-cdn.alpinelinux.org/alpine/edge/main\nhttp://dl-
cdn.alpinelinux.org/alpine/edge/community\nhttp://dl-
cdn.alpinelinux.org/alpine/edge/testing' > /etc/apk/repositories \
&& apk add --no-cache yarn \
&& yarn
EXPOSE 8080
If there is any new dependency registers in package.json, it should be installed when the docker build command is invoked.

Docker Compose gulp is not found in $PATH

I have just started learning docker-compose and I am using a nodejs image. I want to install gulp to create some tasks and have one of them working on the background.
When I run: docker-compose run --rm -d server gulp watch-less
I get this error: ERROR: oci runtime error: container_linux.go:247: starting container process caused "exec: \"gulp\": executable file not found in $PATH"
Here are my file:
# Dockerfile
FROM node:6.10.2
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json /usr/src/app
RUN npm install --quiet
COPY . /usr/src/app
CMD ["npm", "start"]
# docker-compose.yml
version: "2"
services:
server:
build: .
ports:
- "5000:5000"
volumes:
- ./:/usr/src/app
I also have a .dockerignore to ignore the node_modules folder and the npm-debug.log
EDIT:
When I run docker-compose run --rm server npm install package-name I don't have any problem and the package is installed.
Try adding gulp install in Dockerfile:
# Dockerfile
FROM node:6.10.2
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
RUN npm install -g gulp
COPY package.json /usr/src/app
RUN npm install --quiet
COPY . /usr/src/app
CMD ["npm", "start"]
I have found a solution that works but maybe is not the best solution. I have created an script that runs a gulp task on the package.json and if I run:
docker-compose run --rm server npm run gulp_task it works and does what it has to do.
I find that just referencing gulp via
./node_modules/.bin/gulp
instead of directly works fine. ./node_modules/.bin isn't in the path by default. Another option would be to add that dir to the PATH.

Resources