Making volumes with Docker-Compose

I am trying to use Docker to make an API with NodeJS. This is how the directory of my project looks like:

  • Dockerfile
  • docker-compose.yml
  • package.json
  • server.js
  • online_app/ (empty folder)

What I want to do is to have an “online_app” folder which will contain the files of my projects. The problem is that when I try to map this folder as a volume, NodeJS fails because it don’t find the “server.js” and “package.json” file. This is the content of the files (I think that the mistake should be in the “docker-compose.yml” or in the “Dockerfile”:

Dockerfile

FROM node

RUN mkdir /app
WORKDIR /app

COPY . /app
RUN npm install

EXPOSE 8080

CMD ["npm", "start"]

docker-compose.yml

version: "2"

services:
  web:
    build: .
    volumes:
      - ./online_app:/app
    expose:
      - "8080"
    environment:
      - VIRTUAL_HOST=api.quick-cashier.ga,api.quickcashier.eu
      - VIRTUAL_PORT=8080
  mongo:
    image: mongo
    ports:
      - "27017:27017"
networks:
  default:
    external:
      name: proxy_net

package.json

{
  "name": "node_server",
  "version": "0.0.1",
  "description": "",
  "main": "server.js",
  "scripts": {
    "start": "nodemon server.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.16.2",
    "mongoose": "^5.0.3",
    "nodemon": "^1.14.12"
  }
}

server.js

var express = require('express');
var app = express();

var db = require('mongoose');
db.connect("mongodb://mongo:27017");

app.get('/', function(req, res){
  res.send("Hello World!<br>\nHola Mundo!<br>\n");
});

app.listen(8080, function(){
  console.log('Node app listening on port 8080!');
});

i don’t quite understand…

the volumes

volumes:
      - ./:/app 

means to map the current directory (./) to the containers /app folder…
this will overlay the /app folder in the container (the good stuff) with whatever
is in the current directory at the time of docker-compose up

but… you have already copied . into /app during build

also, why copy the package file only then copy everything later

COPY package.json /app
RUN npm install

COPY . /app

just copy everything and THEN do the npm install.

Sorry, I copied the wrong “docker-compose.yml” file. I corrected it in my first post:

volumes:
       - ./online_app:/app

You are right, I should only copy the package.json ones. I have corrected it in the first post, but I still have problems with the mapping of the folder …

The thing is that I copy all these files in the Dockerfile (when I do “COPY . /app”), but when the volume is mounted, all that files are missing …

right,… you overlayed the internal /app (built at image build time) files with whatever is in ./online_app at run time…

Ahhh … now I understand. Sorry for my ignorance, but there is a way to do the reverse thing? I mean, it is possible that the content of the “/app” directory of the container is preserved instead of the content in the “online_app” (in the host)?

Thanks for your reply

don’t mount the volume, or mount it someplace else…

what does online_app add to the node application?

I was planning to use the “online_app” folder to keep always a copy of the original code. But as this does not work as I supposed, I think that I am going to pass …

Thanks for your help :wink:

1 Like

It’s good practice to copy just the package.json file and perform installation before copying the rest of the files. The reason is; if you do so, a layer will be created for your installation process and cached. So every time you build your image, it will skip the installation process unless you made some changes in the package.json file.

2 Likes