My dockerfile will run npm install, however after docker-compose build
the folder node_modules in my host folder remains empty even after seeing building. How can i get the folder up and reflected in the host too?
This is docker-compose.yml:
This is my docker-compose
version: "2"
volumes:
mongostorage:
services:
app:
build: ./app
ports:
- "3000"
links:
- mongo
- redis
command: node ./bin/www
nginx:
build: ./nginx
ports:
- "80:80"
links:
- app:app
mongo:
image: mongo:latest
environment:
- MONGO_DATA_DIR=/data/db
volumes:
- mongostorage:/data/db
ports:
- "27017:27017"
redis:
image: redis
volumes:
- ./data/redis/db:/data/db
ports:
- "6379:6379"
This is dockerfile in app
FROM node:6.3
RUN mkdir -p /var/www/app
WORKDIR /var/www/app
VOLUME /var/www/app
COPY . /var/www/app
COPY package.json /var/www/app
RUN npm install
package.json
{
"name": "app",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node app.js"
},
"dependencies": {
"body-parser": "^1.13.3",
"cookie-parser": "~1.3.5",
"debug": "~2.2.0",
"express": "~4.13.1",
"helmet": "^3.0.0",
"jade": "~1.11.0",
"redis": "^2.6.2",
"serve-favicon": "~2.3.0"
},
"devDependencies": {
"gulp": "^3.9.1",
"gulp-autoprefixer": "^3.1.1",
"gulp-complexity": "^0.3.2",
"gulp-concat": "^2.6.1",
"gulp-cssnano": "^2.1.2",
"gulp-less": "^3.3.0",
"gulp-uglify": "^1.5.4",
"gulp-watch": "^4.3.11",
"strip-debug": "^1.1.1",
"util": "^0.10.3"
}
}
docker logs
for the app container returns after docker-compose up
error:
module.js:442
throw err;
^
Error: Cannot find module 'dotenv'
at Function.Module._resolveFilename (module.js:440:15)
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> (/var/www/nodeapp/app.js:3:1)
at Module._compile (module.js:541:32)
at Object.Module._extensions..js (module.js:550:10)
at Module.load (module.js:458:32)
at tryModuleLoad (module.js:417:12)
at Function.Module._load (module.js:409:3)
starting fresh..
The following is, I believe, what you are asking for, but I'm not sure it's what you want.
What is the actual use case you are trying to address?
If it is to be able to develop your app, modifying files on your local system and have them reflected in the docker container this is not the way to do it..
I have used the npm module serve
as an easy way to keep the container running.
I have used a named volume to make things easier. The volume data
is defined in docker-compose and mounted on /var/www/app
.
fyi, you could also try moving the VOLUME instruction in your original Dockerfile to the bottom as at https://docs.docker.com/engine/reference/builder/#volume:
Changing the volume from within the Dockerfile: If any build steps change the data within the volume after it has been declared, those changes will be discarded.
But this still only defines the volume mount point in the container, you still need to mount it on the host at run time.
App files:
$ tree
.
├── app
│ ├── Dockerfile
│ └── package.json
└── docker-compose.yml
1 directory, 3 files
$ cat app/Dockerfile
FROM node:6.3
RUN mkdir -p /var/www/app
WORKDIR /var/www/app
COPY . /var/www/app
RUN npm install
$ cat app/package.json
{
"name": "app",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "serve"
},
"dependencies": {
"serve": "*"
}
}
$ cat docker-compose.yml
version: "2"
services:
app:
build: ./app
ports:
- "3000"
command: npm start
volumes:
- data:/var/www/app
volumes:
data:
Build the app:
$ docker-compose build app
Building app
Step 1/5 : FROM node:6.3
---> 0d9089853221
Step 2/5 : RUN mkdir -p /var/www/app
---> Using cache
---> 18cc43628367
Step 3/5 : WORKDIR /var/www/app
---> Using cache
---> b8fa2b1a2624
Step 4/5 : COPY . /var/www/app
---> de38a6c3f784
Step 5/5 : RUN npm install
---> Running in 5a035f687de1
npm info it worked if it ends with ok
npm info using npm@3.10.3
npm info using node@v6.3.1
npm info attempt registry request try #1 at 1:19:21 PM
npm http request GET https://registry.npmjs.org/serve
...
npm info ok
---> 76b99c707ac1
Removing intermediate container 5a035f687de1
Successfully built 76b99c707ac1
Successfully tagged 47173020_app:latest
Bring up the app
$ docker-compose up -d app
Recreating 47173020_app_1 ...
Recreating 47173020_app_1 ... done
Check the app logs
$ docker-compose logs app
Attaching to 47173020_app_1
app_1 | npm info it worked if it ends with ok
app_1 | npm info using npm@3.10.3
app_1 | npm info using node@v6.3.1
app_1 | npm info lifecycle app@0.0.0~prestart: app@0.0.0
app_1 | npm info lifecycle app@0.0.0~start: app@0.0.0
app_1 |
app_1 | > app@0.0.0 start /var/www/app
app_1 | > serve
app_1 |
app_1 | serve: Running on port 5000
Now the volume you are looking for on the host is on the docker host running as a vm on your local machine and can only be accessed from a running container.
I have taken the following from Inspecting Docker Volumes on a Mac/Windows the Easy Way which you can refer to for more detail.
List the docker volumes
$ docker volume ls
local 47173020_data
Inspect the volume to get it's mount point
$ docker volume inspect 47173020_data
[
{
"CreatedAt": "2017-11-13T13:15:59Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/47173020_data/_data",
"Name": "47173020_data",
"Options": {},
"Scope": "local"
}
]
Start up a simple container, mount "/docker" on the host root, and list the files in the volume which are the ones copied and created by the Dockerfile
$ docker run --rm -it -v /:/docker alpine:edge ls -l /docker/var/lib/docker/volumes/47173020_data/_data
total 12
-rw-r--r-- 1 root root 119 Nov 13 12:30 Dockerfile
drwxr-xr-x 153 root root 4096 Nov 13 13:14 node_modules
-rw-r--r-- 1 root root 144 Nov 13 13:03 package.json
That VOLUME instruction is mounting your app directory to the host which would be hiding anything you put in there on the container. I'm actually surprised that you see the node_modules directory. You don't need the COPY package.json
instruction either as the COPY .
should take care of that. Try the following Dockerfile instead..
FROM node:6.3
RUN mkdir -p /var/www/app
WORKDIR /var/www/app
COPY . /var/www/app
RUN npm install
This works fine for me using the info you have provided.
Running docker-compose build
from the directory which contains the Dockerfile builds the image successfully.
$ tree
.
├── app
│ ├── Dockerfile
│ └── package.json
└── docker-compose.yml
1 directory, 3 files
$ cat docker-compose.yml
version: "2"
services:
app:
build: ./app
ports:
- "3000"
command: node ./bin/www
$ cat app/Dockerfile
FROM node:6.3
RUN mkdir -p /var/www/app
WORKDIR /var/www/app
COPY . /var/www/app
RUN npm install
$ cat app/package.json
{
"name": "app",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node app.js"
},
"dependencies": {
"body-parser": "^1.13.3",
"cookie-parser": "~1.3.5",
"debug": "~2.2.0",
"express": "~4.13.1",
"helmet": "^3.0.0",
"jade": "~1.11.0",
"redis": "^2.6.2",
"serve-favicon": "~2.3.0"
},
"devDependencies": {
"gulp": "^3.9.1",
"gulp-autoprefixer": "^3.1.1",
"gulp-complexity": "^0.3.2",
"gulp-concat": "^2.6.1",
"gulp-cssnano": "^2.1.2",
"gulp-less": "^3.3.0",
"gulp-uglify": "^1.5.4",
"gulp-watch": "^4.3.11",
"strip-debug": "^1.1.1",
"util": "^0.10.3"
}
}
run the build..
$ docker-compose build
Building app
Step 1/5 : FROM node:6.3
6.3: Pulling from library/node
357ea8c3d80b: Pull complete
...
646e6da4bf07: Pull complete
Digest: sha256:cde2bd38dbfec5e6e2981ec7a05056c734148fcd4bff088e143f11b2bafe3b64
Status: Downloaded newer image for node:6.3
---> 0d9089853221
Step 2/5 : RUN mkdir -p /var/www/app
---> Running in 018dd9b28c57
---> 18cc43628367
Removing intermediate container 018dd9b28c57
Step 3/5 : WORKDIR /var/www/app
---> b8fa2b1a2624
Removing intermediate container ba1ad506cab2
Step 4/5 : COPY . /var/www/app
---> 3f37c76acdc4
Step 5/5 : RUN npm install
---> Running in dd87c26c2546
npm info it worked if it ends with ok
npm info using npm@3.10.3
npm info using node@v6.3.1
npm info attempt registry request try #1 at 11:39:41 AM
npm http request GET https://registry.npmjs.org/body-parser
...
npm info lifecycle util@0.10.3~postinstall: util@0.10.3
npm info lifecycle app@0.0.0~preinstall: app@0.0.0
npm info linkStuff app@0.0.0
npm info lifecycle app@0.0.0~install: app@0.0.0
npm info lifecycle app@0.0.0~postinstall: app@0.0.0
npm info lifecycle app@0.0.0~prepublish: app@0.0.0
app@0.0.0 /var/www/app
+-- body-parser@1.18.2
| +-- bytes@3.0.0
...
npm WARN optional Skipping failed optional dependency /chokidar/fsevents:
npm WARN notsup Not compatible with your operating system or architecture: fsevents@1.1.2
npm info ok
---> d1bfc665f54c
Removing intermediate container dd87c26c2546
Successfully built d1bfc665f54c
Successfully tagged so47173020_app:latest
modifying the Dockerfile command as done below I am able to run docker-compose up app
and see all the modules installed in the node_modules directory.
version: "2"
services:
app:
build: ./app
ports:
- "3000"
command: ls -la node_modules
output of docker-compose up app
:
Creating so47173020_app_1 ...
Creating so47173020_app_1 ... done
Attaching to so47173020_app_1
app_1 | total 2004
app_1 | drwxr-xr-x 497 root root 20480 Nov 10 11:40 .
app_1 | drwxr-xr-x 1 root root 4096 Nov 10 11:40 ..
app_1 | drwxr-xr-x 2 root root 4096 Nov 10 11:40 .bin
app_1 | drwxr-xr-x 2 root root 4096 Nov 10 11:40 accepts
app_1 | drwxr-xr-x 4 root root 4096 Nov 10 11:40 accord
...
app_1 | drwxr-xr-x 3 root root 4096 Nov 10 11:40 x-xss-protection
app_1 | drwxr-xr-x 2 root root 4096 Nov 10 11:40 xtend
app_1 | drwxr-xr-x 3 root root 4096 Nov 10 11:40 yargs
so47173020_app_1 exited with code 0