Docker compose volume mapping with NodeJS app

2019-07-27 03:03发布

问题:

I am trying to achieve something incredibly basic, but have been going at this for a couple of evenings now and still haven't found a solid (or any) solution. I have found some similar topics on SO and followed what was on there but to no avail, so I have created a GitHub repo for my specific case.

What I'm trying to do:

  • Be able to provision NodeJS app using docker-compose up -d (I plan to add further containers in future, omitted from this example)
  • Ensure the code is mapped via volumes so I don't have to re-build every time I make a change to some code locally.

My guess is the issue I'm encountering is something to do with the mapping of volumes causing some files to be lost/overwritten within the container, for instance in some of the variations I've tried the folders are being mapped but individual files are not.

I've created a simple repo to illustrate my issue, just checkout and run docker-compose up -d to see the issue, the container dies due to:

Error: Cannot find module '/src/app/app.js'

The link to the repo is here: https://github.com/josephmcdermott/nodejs-docker-issue, PR's welcome and if anybody can solve this for me I'd be eternally grateful.

UPDATE: please see the solution code below, kind thanks to ldg

Dockerfile

FROM node:4.4.7

RUN mkdir -p /src
COPY . /src
WORKDIR /src
RUN npm install

EXPOSE 3000

CMD ["node", "/src/app.js"]

docker-compose.yml

app:
  build: .
  volumes:
    - ./app:/src/app

Folder Structure:

- app
- - * (files I want to sync and regularly update)
- app.js (initial script to call files within app/)
- Dockerfile
- docker-compose.yml
- package.json

回答1:

In your compose file, the last line - /src/app/node_modules is likely mapping over your previous volume. If you mount /scr/app then node_modules will get created in that linked volume. So it would look like this:

app:
  build: .
  volumes:
    - ./app:/src/app

If you do want to keep your entire /app directory as a linked volume, you'll need to either do npm install when starting the container (which would insure it picks up any updates) OR don't link the volume and update your Dockerfile to copy the entire /app directory. This is nice because it gives you a self-contained image. I usually Dockerize my Node.js apps this way. You can also run npm test as appropriate to verify the image.

If you need to create a linked volume for a script file you want to be able to edit (or if your app generates side-effects), you can link just that directory or file via Docker volumes.

Btw, if you want to make sure you don't copy the contents of that directory in the future, add it to .dockerignore (as well as .gitignore).