So I have this NodeJS express app. This is code works:
Dockerfile
FROM node:10.16-alpine
WORKDIR /app
COPY . /app
RUN npm install
CMD ["npm", "start"]
docker-pose.yml
version: "3.7"
services:
node-express:
build: .
ports:
- 80:3000
But for this app I want to see the live code changes. So I know that is where you can use Bind Mounts, but as soon as I add the volumes like so:
docker-pose.yml
version: "3.7"
services:
node-express:
build: .
volumes:
- .:/app
ports:
- 80:3000
It looks like the node_modules is not in the "app" directory anymore.. How can I fix this? I've worked on this for four hours, and I still can't spot the mistake!
Error
HijackManiac:webserver hijackmaniac$ docker-pose up
Creating network "webserver_default" with the default driver
Building node-express
Step 1/5 : FROM node:10.16-alpine
---> a298c79121d9
Step 2/5 : WORKDIR /app
---> Running in 9b99df0f54ba
Removing intermediate container 9b99df0f54ba
---> 48f9b606b32d
Step 3/5 : COPY . /app
---> 1f29dc735dc7
Step 4/5 : RUN npm install
---> Running in 81225f56a9fd
npm WARN [email protected] No description
npm WARN [email protected] No repository field.
added 106 packages from 130 contributors and audited 202 packages in 3.344s
found 0 vulnerabilities
Removing intermediate container 81225f56a9fd
---> 2985dc77bc12
Step 5/5 : CMD ["npm", "start"]
---> Running in 271ab42687ce
Removing intermediate container 271ab42687ce
---> 38a39768792e
Successfully built 38a39768792e
Successfully tagged webserver_node-express:latest
WARNING: Image for service node-express was built because it did not already exist. To rebuild this image you must use `docker-pose build` or `docker-pose up --build`.
Creating webserver_node-express_1 ... done
Attaching to webserver_node-express_1
node-express_1 |
node-express_1 | > [email protected] start /app
node-express_1 | > node src/app.js
node-express_1 |
node-express_1 | internal/modules/cjs/loader.js:638
node-express_1 | throw err;
node-express_1 | ^
node-express_1 |
node-express_1 | Error: Cannot find module 'express'
node-express_1 | at Function.Module._resolveFilename (internal/modules/cjs/loader.js:636:15)
node-express_1 | at Function.Module._load (internal/modules/cjs/loader.js:562:25)
node-express_1 | at Module.require (internal/modules/cjs/loader.js:690:17)
node-express_1 | at require (internal/modules/cjs/helpers.js:25:18)
node-express_1 | at Object.<anonymous> (/app/src/app.js:2:17)
node-express_1 | at Module._pile (internal/modules/cjs/loader.js:776:30)
node-express_1 | at Object.Module._extensions..js (internal/modules/cjs/loader.js:787:10)
node-express_1 | at Module.load (internal/modules/cjs/loader.js:653:32)
node-express_1 | at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
node-express_1 | at Function.Module._load (internal/modules/cjs/loader.js:585:3)
node-express_1 | npm ERR! code ELIFECYCLE
node-express_1 | npm ERR! errno 1
node-express_1 | npm ERR! [email protected] start: `node src/app.js`
node-express_1 | npm ERR! Exit status 1
node-express_1 | npm ERR!
node-express_1 | npm ERR! Failed at the [email protected] start script.
node-express_1 | npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
node-express_1 | npm WARN Local package.json exists, but node_modules missing, did you mean to install?
node-express_1 |
node-express_1 | npm ERR! A plete log of this run can be found in:
node-express_1 | npm ERR! /root/.npm/_logs/2019-06-04T23_55_20_327Z-debug.log
webserver_node-express_1 exited with code 1
See working tree:
Before I added the volume in the docker-pose.yml, the container runs succesfully. This is the structure:
So I have this NodeJS express app. This is code works:
Dockerfile
FROM node:10.16-alpine
WORKDIR /app
COPY . /app
RUN npm install
CMD ["npm", "start"]
docker-pose.yml
version: "3.7"
services:
node-express:
build: .
ports:
- 80:3000
But for this app I want to see the live code changes. So I know that is where you can use Bind Mounts, but as soon as I add the volumes like so:
docker-pose.yml
version: "3.7"
services:
node-express:
build: .
volumes:
- .:/app
ports:
- 80:3000
It looks like the node_modules is not in the "app" directory anymore.. How can I fix this? I've worked on this for four hours, and I still can't spot the mistake!
Error
HijackManiac:webserver hijackmaniac$ docker-pose up
Creating network "webserver_default" with the default driver
Building node-express
Step 1/5 : FROM node:10.16-alpine
---> a298c79121d9
Step 2/5 : WORKDIR /app
---> Running in 9b99df0f54ba
Removing intermediate container 9b99df0f54ba
---> 48f9b606b32d
Step 3/5 : COPY . /app
---> 1f29dc735dc7
Step 4/5 : RUN npm install
---> Running in 81225f56a9fd
npm WARN [email protected] No description
npm WARN [email protected] No repository field.
added 106 packages from 130 contributors and audited 202 packages in 3.344s
found 0 vulnerabilities
Removing intermediate container 81225f56a9fd
---> 2985dc77bc12
Step 5/5 : CMD ["npm", "start"]
---> Running in 271ab42687ce
Removing intermediate container 271ab42687ce
---> 38a39768792e
Successfully built 38a39768792e
Successfully tagged webserver_node-express:latest
WARNING: Image for service node-express was built because it did not already exist. To rebuild this image you must use `docker-pose build` or `docker-pose up --build`.
Creating webserver_node-express_1 ... done
Attaching to webserver_node-express_1
node-express_1 |
node-express_1 | > [email protected] start /app
node-express_1 | > node src/app.js
node-express_1 |
node-express_1 | internal/modules/cjs/loader.js:638
node-express_1 | throw err;
node-express_1 | ^
node-express_1 |
node-express_1 | Error: Cannot find module 'express'
node-express_1 | at Function.Module._resolveFilename (internal/modules/cjs/loader.js:636:15)
node-express_1 | at Function.Module._load (internal/modules/cjs/loader.js:562:25)
node-express_1 | at Module.require (internal/modules/cjs/loader.js:690:17)
node-express_1 | at require (internal/modules/cjs/helpers.js:25:18)
node-express_1 | at Object.<anonymous> (/app/src/app.js:2:17)
node-express_1 | at Module._pile (internal/modules/cjs/loader.js:776:30)
node-express_1 | at Object.Module._extensions..js (internal/modules/cjs/loader.js:787:10)
node-express_1 | at Module.load (internal/modules/cjs/loader.js:653:32)
node-express_1 | at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
node-express_1 | at Function.Module._load (internal/modules/cjs/loader.js:585:3)
node-express_1 | npm ERR! code ELIFECYCLE
node-express_1 | npm ERR! errno 1
node-express_1 | npm ERR! [email protected] start: `node src/app.js`
node-express_1 | npm ERR! Exit status 1
node-express_1 | npm ERR!
node-express_1 | npm ERR! Failed at the [email protected] start script.
node-express_1 | npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
node-express_1 | npm WARN Local package.json exists, but node_modules missing, did you mean to install?
node-express_1 |
node-express_1 | npm ERR! A plete log of this run can be found in:
node-express_1 | npm ERR! /root/.npm/_logs/2019-06-04T23_55_20_327Z-debug.log
webserver_node-express_1 exited with code 1
See working tree:
Before I added the volume in the docker-pose.yml, the container runs succesfully. This is the structure:
Share Improve this question edited Jun 5, 2019 at 9:39 Steven Soekha asked Jun 5, 2019 at 0:01 Steven SoekhaSteven Soekha 8912 gold badges11 silver badges20 bronze badges 3- CAn you post your file structure of project? – Ganesh Karewad Commented Jun 5, 2019 at 4:57
-
1
When you set the work-directory
WORKDIR
means you are already there. Check out your copy statement from Dockerfile. You have copied all current directory to/app
which actually means/app/app
in a container file system. – Rahul Patil Commented Jun 5, 2019 at 7:19 - I don't think that is true, because when I run this docker-pose without "volumes" in the docker-pose.yml. I don't see /app/app. I will upload the picture to this post. – Steven Soekha Commented Jun 5, 2019 at 9:35
2 Answers
Reset to default 3When you mount the volume of your project into the container working directory your overriding any changes you've made since the original copy/add in your Dockerfile with what is in your local project directory. In this case that means the node_modules folder. The easiest way I've found to fix this problem is to not mount the entire project directory, but just a subfolder that has my source code.
You need to either modify your project structure moving every editable code inside a folder let's say src
, or update your Dockerfile to move node_modules
a directory upper.
As we know, when Node can't find node_modules in the current directory, it starts looking for it in the parent directory, so we take advantage of it.
a Dockerfile similar to this will solve your problem.
FROM node:10.16-alpine
WORKDIR /node
COPY package.json package-lock.json ./
RUN npm install
WORKDIR /node/app
COPY . .
CMD ["npm", "start"]
Please make sure to make appropriate changes to the docker-pose.yml too (directory structure has changed)