Error when running node container using docker compose - node.js

When running "docker-compose up", I get the following error:
npm info lifecycle server#1.0.0~dev: server#1.0.0
> server#1.0.0 dev /code/app
> nodemon -L ./bin/www --exec babel-node
sh: 0: getcwd() failed: No such file or directory
path.js:1144
cwd = process.cwd();
^
Error: ENOENT: no such file or directory, uv_cwd at Error (native)
at Object.resolve (path.js:1144:25)
at Function.Module._resolveLookupPaths (module.js:361:17)
at Function.Module._resolveFilename (module.js:431:31)
at Function.Module._load (module.js:388:25)
at Module.require (module.js:468:17)
at require (internal/module.js:20:19)
at Object.<anonymous>
(/usr/local/lib/node_modules/nodemon/bin/nodemon.js:3:11)
at Module._compile (module.js:541:32)
at Object.Module._extensions..js (module.js:550:10)
npm info lifecycle server#1.0.0~dev: Failed to exec dev script
npm ERR! Linux 4.9.36-moby
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "run" "dev"
npm ERR! node v6.3.1
npm ERR! npm v3.10.3
npm ERR! code ELIFECYCLE
npm ERR! server#1.0.0 dev: `nodemon -L ./bin/www --exec babel-node`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the server#1.0.0 dev script 'nodemon -L ./bin/www --
exec babel-node'.
My dockerfile looks like this:
FROM joakimbeng/node-zeromq
RUN mkdir /code/
RUN mkdir /code/app/
COPY package.json /code/
WORKDIR /code
RUN npm install -g nodemon babel-cli
RUN npm install
WORKDIR /code/app
CMD ["npm", "run", "dev"]
And my service like this:
node:
build: ./node/
ports:
- "3000:3000"
volumes:
- ../code:/code/app
links:
- mongodb
- python
environment:
- NODE_ENV=dev
- NODE_PATH=/code/node_modules
- MONGODB_ADDRESS=mongodb
- PYTHON_ADDRESS=python
I've tried to delete all containers and images and run the whole thing again, but the same error appears. It seems to build fine when running "docker-compose build".
What I'm trying to accomplish here is:
1. Let the container handle all the dependencies (node modules)
2. Mount my code base to the container
3. Use nodemon for hot reload

I ended up with something similar to what I did initially. Not sure what caused the error in my OP, but the difference seems to be that I mount my dependencies in a different directory.
Dockerfile:
FROM joakimbeng/node-zeromq
RUN mkdir /code/
RUN mkdir /dependencies/
COPY package.json /dependencies/
WORKDIR /dependencies/
RUN npm install -g nodemon babel-cli
npm install
WORKDIR /code/
CMD bash -c "npm run dev"
Service in docker-compose:
node:
build: ./node/
ports:
- "3000:3000"
volumes:
- ../code/:/code
links:
- mongodb
- python
environment:
- NODE_ENV=dev
- NODE_PATH=/dependencies/node_modules
- MONGODB_ADDRESS=mongodb
- PYTHON_ADDRESS=python
This way my dependencies are only installed on build.

Your issue is the volume sharing. When you share a volume from host to the container. If the folder already exists in the container then the host container will shadow the container folder.
If you have 10 files inside container and 0 files on your host, then after volume mapping your container will see 0 files. Because the the host folder is mounted and it has nothing. So you Dockerfile statement
RUN npm install
Is effectively gone, if the host volume doesn't have the npm install done. Luckily the solution is simple. You can change your CMD to below
CMD bash -c "npm install && npm run dev"
In case you don't want to change the Dockerfile you can add the below in your docker-compose.yml file for the node service
command: bash -c "npm install && npm run dev"
Edit (14-Aug):
If you want your dependencies to be in image then you need to make few changes in your docker-compose.yml, what you need is the internal code to be left alone and just linking the node_modules from that directory to a you app directory
node:
build: ./node/
ports:
- "3000:3000"
volumes:
- ../code:/code/app
command: bash -c "ln -fs /code/node_modules /code/app/node_modules && exec npm run dev"
links:
- mongodb
- python
environment:
- NODE_ENV=dev
- NODE_PATH=/code/node_modules
- MONGODB_ADDRESS=mongodb
- PYTHON_ADDRESS=python
Another point i notice is that your running package.json install in /code and putting your code /code/app which is probably wrong when you run the image. But with the new edit I have suggested above, this should work

Related

Error while running Node application with Docker: db-on-docker#1.0.0 start: `node index.js`

I have developed a Nodejs application with Docker but when I run the application I get the error:
module.js:550
throw err;
^
Error: Cannot find module 'express'
at Function.Module._resolveFilename (module.js:548:15)
at Function.Module._load (module.js:475:25)
at Module.require (module.js:597:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (/usr/src/app/index.js:1:81)
at Module._compile (module.js:653:30)
at Object.Module._extensions..js (module.js:664:10)
at Module.load (module.js:566:32)
at tryModuleLoad (module.js:506:12)
at Function.Module._load (module.js:498:3)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! db-on-docker#1.0.0 start: `node index.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the db-on-docker#1.0.0 start 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?
npm ERR! A complete log of this run can be found in:
npm ERR! /root/.npm/_logs/2022-01-30T05_34_13_500Z-debug.log
Following are my files:
DockerFile present within web folder:
FROM node:8
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 9000
CMD ["npm","start"]
CMD tail -f /dev/null
Following is my docker-compose.yml file present within my root project folder:
version: '3'
services:
db:
container_name: db
image: mysql:5.7
volumes:
- "./data/mysql:/var/lib/mysql:rw"
environment:
MYSQL_DATABASE: db
MYSQL_ROOT_PASSWORD: 123456
MYSQL_USER: admin
MYSQL_PASSWORD: 123456
DATABASE_HOST: localhost
restart: always
web:
container_name: web
image: node:8
volumes:
- ./web:/usr/src/app
working_dir: /usr/src/app
depends_on:
- db
restart: on-failure
command: "tail -f /dev/null"
environment: ["project=${project}", "type=${type}"]
I did the following things:
docker-compose build -d to load all images.
docker-comoise up -d to bring-up all the images and confirmed the same using docker-compose ps.
Then ran the application using the command docker-compose exec web sh -c "project=myproject type=New npm start"
When I run the 3rd step I get the error as provided above. This was working previously when I developed the application. Now I am trying to run the same application in another system but getting this error. Unable to follow what might be wrong.
I have added the express using npm install so I guess its not due to that but due to the line npm ERR! Failed at the db-on-docker#1.0.0 start script., I tried to install express using npm install --save express, deleted the node_modules folder. Tried the npm install but nothing seems to work for me.
Can someone please let me know what I need to do?
There is one thins missing there in your docker-compose.yml file:
You don't tell docker to build your Dockerfile, instead, just grab the image node:8 from docker registry, but how does docker know that you need to install your packages?
You have to add this block under web service in docker-compose.yml file:
build:
context: ./web
One more thing to mention is that, you're overriding the default command that you declared in Dockerfile, you can remove this line from docker-compose.yml file
command: "tail -f /dev/null"
Honestly, I don't know why you need this here.
You can also try to remove this instruction from Dockerfile:
CMD tail -f /dev/null
I think npm start is enough
Note: npm start requires that you define the entry point in your package.json file, otherwise, you will get an error
One lat thing and back you the error you've mentioned herewith in your question:
The reason is because the container can't find express module installed inside the image you're using node:8 in this case, because you just use the image and map your project directory to the container without installing the dependencies.

Docker image build but can't see in browser

I have an Angular project which I built an image, it runs in local, in other words, I can launch it with npm start, and see my app on localhost:4200.
But when I build it, I can't see the project in the browser on the same url. It's just my browser telling me it's unable to connect. I also used Postman same error.
Dockerfile :
FROM node:latest
# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install
# Bundle app source
COPY . /usr/src/app
EXPOSE 4200
CMD [ "npm", "start" ]
The command
docker build -t test-front .
...
docker run -it -p 4200:4200 test-front
It builds the image and run it well, but I can't access it on the browser.
I used the answer to this question to remake my Dockerfile:
Cannot find module for a node js app running in a docker compose environment
What I did:
I did a `docker exec -it NAME_OF_THE_CONTAINER /bin/bash` to get inside the container, I then retried `npm start` inside the container.
Since the port 4200 was in use, it asked me to use another port:
root#a66d5cff3e64:/usr/src/app# npm start
> xxx#0.0.0 start
> ng serve
? Port 4200 is already in use.
Would you like to use a different port? Yes
✔ Browser application bundle generation complete.
...
** Angular Live Development Server is listening on localhost:43225, open your browser on http://localhost:43225/ **
The project was launching correctly in the container, no error message.
I think, the container doesn't expose the port correctly.
Checking port
I used the command:
user#user:~/front$ docker port <container_name>
4200/tcp -> 0.0.0.0:4200
4200/tcp -> :::4200
This is what I have.
Small detail
I'd like to precise, that using node:boron in Dockerfile, made the docker run break. It didn't worked when I used docker run command.
With the message:
> xxxxxx#0.0.0 start /usr/src/app
> ng serve
/usr/src/app/node_modules/#angular/cli/bin/ng:26
);
^
SyntaxError: Unexpected token )
at createScript (vm.js:56:10)
at Object.runInThisContext (vm.js:97:10)
at Module._compile (module.js:549:28)
at Object.Module._extensions..js (module.js:586:10)
at Module.load (module.js:494:32)
at tryModuleLoad (module.js:453:12)
at Function.Module._load (module.js:445:3)
at Module.runMain (module.js:611:10)
at run (bootstrap_node.js:394:7)
at startup (bootstrap_node.js:160:9)
npm ERR! Linux 5.11.0-22-generic
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "start"
npm ERR! node v6.17.1
npm ERR! npm v3.10.10
npm ERR! code ELIFECYCLE
npm ERR! xxxx#0.0.0 start: `ng serve`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the xxxx#0.0.0 start script 'ng serve'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the xxx package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! ng serve
npm ERR! You can get information on how to open an issue for this project with:
npm ERR! npm bugs xxx
npm ERR! Or if that isn't available, you can get their info via:
npm ERR! npm owner ls xxx
npm ERR! There is likely additional logging output above.
npm ERR! Please include the following file with any support request:
npm ERR! /usr/src/app/npm-debug.log
I've changed my last line to CMD [ "npm", "run", "ng", "serve", "-host", "0.0.0.0" ].
I can build the image, but when I run it, I get:
> t-maj-voltron-front#0.0.0 ng
> ng "serve" "0.0.0.0"
Project '0.0.0.0' does not exist.
npm notice
npm notice New minor version of npm available! 7.15.1 -> 7.19.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v7.19.0
npm notice Run npm install -g npm#7.19.0 to update!
npm notice
a working Dockerfile:
# base image
FROM node:12.14
# install chrome for protractor tests
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
RUN sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
RUN apt-get update && apt-get install -yq google-chrome-stable
# set working directory
WORKDIR /app
# add `/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:$PATH
# install and cache app dependencies
COPY package.json /app/package.json
RUN npm install
RUN npm install -g #angular/cli#7.3.9
# add app
COPY . /app
EXPOSE 4200
# start app
CMD ng serve --host 0.0.0.0
I believe you're missing the port forwarding between the exposed port and your local host.
You can portforward via the -p or --expose flag and the <localport>:<containerport>
In your case:
docker run -it -p 4200:4200 test-front
Will forward traffic from localhost:4200 into your container
EDIT
I did some more reading and it looks like there's an additional step when working with angular in docker.
try editing your npm start command to ng serve --host 0.0.0.0. As explained very thoroughly by Juan adding the --host flag will "listen to all the interfaces from the 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.

How can I run jshint in my CI using Docker

I am trying to create a task in our Azure pipeline to validate our javascript.
We have a node container which performs an npm install when spun up:
node:
image: node:12-alpine
user: "node"
working_dir: /home/node/app
environment:
- NODE_ENV=development
volumes:
- ./:/home/node/app
expose:
- "8081"
command: "npm install"
To perform my task I have created a make command in the Makefile:
js-check: ## Run Jshint
docker-compose run node npm install && npm run jshint
Which I then call in the build job as follows:
- script: make js-check
displayName: 'Run JSHint'
Locally when I call the make js-check it performs the install, followed by the jshint which outputs 0 vulnerabilities found. However when the pipeline reaches this task remotely it fails claiming missing write access to /home/node/app
npm WARN checkPermissions Missing write access to /home/node/app
npm ERR! code EACCES
npm ERR! syscall access
npm ERR! path /home/node/app
npm ERR! errno -13
npm ERR! Error: EACCES: permission denied, access '/home/node/app'
npm ERR! [Error: EACCES: permission denied, access '/home/node/app'] {
npm ERR! errno: -13,
npm ERR! code: 'EACCES',
npm ERR! syscall: 'access',
npm ERR! path: '/home/node/app'
npm ERR! }
npm ERR!
npm ERR! The operation was rejected by your operating system.
npm ERR! It is likely you do not have the permissions to access this file as the current user
npm ERR!
npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator.
Your Makefile runs two commands; the shell interprets the && marker before it gets to Docker. That command is equivalent to:
js-check: ## Run Jshint
docker-compose run node npm install
npm run jshint # (without Docker)
It looks like your environment already has Node installed. You need to resolve the permissions issues (generally the CI system will check out source trees as a user that can run commands), and then you can use this native Node:
js-install: package.json
npm install
js-check: js-install
npm run jshint
This has the advantage of only depending on normal Javascript development tools; you don't need the extra docker-compose.yml file or administrator privileges just to run your unit tests.
If you really need to run this in Docker, you can either run this as two separate commands, or make the single container command be a shell that can interpret the && itself:
js-install1: package.json docker-compose.yml
docker-compose run node npm install
js-check1: js-install1
docker-compose run node npm run jshint
js-check2: package.json docker-compose.yml
docker-compose run node \
sh -c "npm install && npm run jshint"
Above error is because /home/node directory is owned by the node user in the default node image. The /app directory is created and owned by root. See this open issue about above error for more information.
I reproduced the same error with your compose file. When i changed the user to root. The error was gone.
So you can try changing the user to root instead of node in your compose file.
node:
image: node:12-alpine
user: "root"
working_dir: /home/node/app
As David pointed out, you also need to change your makefile to docker-compose run node sh -c "npm install && npm run jshint". if you want to run the commands in docker.
Another workaround is to build and run your container from a dockerfile instead of the compose file. See below simple example dockerfile.
from node:12-alpine
ENV NODE_ENV=development
RUN mkdir -p /home/node/app
RUN chown -R node:node /home/node/app
USER node
WORKDIR /home/node/app
COPY . ./
RUN npm install
CMD [ "npm", "run", "jshint" ]
Then change the Makefile like example:
js-check: ## Run Jshint
docker build --tag nodejshint:1.0 . && docker run --detach --name jshintContainer nodejshint:1.0

npm script fails with sh: 1: <command>: not found in docker container

Question
When running npm run start:debug command inside a docker container, I get this error:
# npm run start:debug
> api#0.0.0 start:debug /usr/src/api
> nest start -e "node --inspect-brk 0.0.0.0:9229" --watch -p tsconfig.json
sh: 1: nest: not found
npm ERR! code ELIFECYCLE
npm ERR! syscall spawn
npm ERR! file sh
npm ERR! errno ENOENT
npm ERR! api#0.0.0 start:debug: `nest start -e "node --inspect-brk 0.0.0.0:9229" --watch -p tsconfig.json`
npm ERR! spawn ENOENT
Running npm ls --depth=0 shows that I have #nestjs/cli installed:
# npm ls --depth=0
api#0.0.0 /usr/src/api
+-- #nestjs/cli#6.14.2
+-- #nestjs/common#6.11.11
...
Why isn't the nest cli binary being found?
My Setup
This is how I launch the shell:
docker-compose -f docker-compose-base.yml -f docker-compose-dev.yml run api /bin/sh
My docker-compose files:
# -base
version: '3'
services:
api:
build: .
restart: on-failure
volumes:
- /usr/src/api/node_modules
container_name: api
# -dev
version: '3'
networks:
# Use lb_lbnet network created by the load balancer repo (lb)
# We do this because we need the load balance to resolve container names defined here to forward traffic
# This is only needed for dev
default:
external:
name: lb_lbnet
services:
db:
image: postgres:11
container_name: db
restart: always
env_file:
- ./db.env # uses POSTGRES_DB and POSTGRES_PASSWORD to create a fresh db with a password when first run
volumes:
- ./postgres-data:/var/lib/postgresql/data
# only used to upload DB dump:
# - ./backup:/tmp/backup
api:
restart: 'no'
build:
context: .
args:
NODE_ENV: development
depends_on:
- db
ports:
- 9229:9229
volumes:
- ./:/usr/src/api
- ./node_modules:/usr/src/api/node_modules
# enable to debug hgezim-express-shopify-auth
- ../../hgezim-express-shopify-auth:/usr/hgezim-express-shopify-auth
env_file:
- .env
command: /bin/bash -c 'echo "Starting" && npm install && npm run start:debug'
My Dockerfile:
FROM node:12
WORKDIR /usr/src/api
COPY package*.json ./
ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}
RUN npm install # && npm ls --depth=0 # commented this out since it returns non-zero exit code
COPY . .
VOLUME [ "/usr/src/api/node_modules" ]
RUN ["/usr/local/bin/npm", "run","lint"]
RUN ["/usr/local/bin/npm", "run","build"]
# not using an execution list here so we get shell variable substitution
CMD /bin/bash -c 'npm run start:$NODE_ENV'
Nest CLI needs to be installed globally for the command line to work. Looks like you have it installed locally via package.json so nest was not added to PATH. Either add RUN npm install -g #nestjs/cli to your Dockerfile, or change start:debug script to use the local version (something like node_modules/<nestcli module>/.bin/nest).

Resources