I'm working with a team on a repo built in Docker and Node. When someone else installs node packages, I git pull
those changes to package.json
and package-lock.json
.
I can't just run docker-compose build
and then docker-compose up
, though, to install these new node packages. I have to first docker-compose down -v
. This is because we're using a volume to store the node modules. We're not tied to this, and frankly would rather just store the modules in a docker image layer. But then, when we bind the app volume (- .:/app
in docker-compose.yml
), the node_modules
folder in the image is shadowed.
It feels like we're taking the wrong approach to this, but this seems to be what the generally accepted practice is. Our setup is based on "Lessons from Building a Node App in Docker"
Our Dockerfile
:
FROM node:8.4.0
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install --loglevel=error --progess=false
COPY . /app/
Our docker-compose.yml
:
---
version: '2.1'
services:
main:
build:
context: .
volumes:
- .:/app
- /app/node_modules
container_name: main
command: ['node', 'index.js']
My understanding of the issue is that, in the docker-compose.yml
file, The volume - /app/node_modules
creates a volume that copies the node modules from inside the image layer into a volume, meaning that when we build the app again with a different package.json
, the image is updated but not the volume. down
ing the volume forces it to re-copy from the updated image node_modules
, which is why that works. Please let me know if my understanding is incorrect :)
We're running in AWS ECS, so unfortunately we can only use docker features available in 17.03.2-ce (no multi-stage docker files for now).
This is an old question but in case anyone else comes here with the same issue, I struggled with this too and this is how I could achieve the desired behaviour:
docker-compose up --build --renew-anon-volumes
According to the documentation on docker-compose up
https://docs.docker.com/engine/reference/commandline/compose_up/
Option | Short | Description |
---|---|---|
--renew-anon-volumes | -V | Recreate anonymous volumes instead of retrieving data from the previous containers. |
With this, you not only build a new image, but also override the original volume used to store node_modules
. Note that it doesn't work with named volumes. If you use named volumes, you'd need to manually remove that volume with docker volume rm <volume-name>
before running docker-compose up
again.
The understanding of how volumes work from the original question seems sound. Readers may also find the following discussion in the Github issue beneficial to understanding it.
https://github.com/moby/moby/issues/30647#issuecomment-276882545