I use docker and docker-compose for development. I have a nextjs application that uses yarn as a package manager. My
docker-compose.yml file looks like this:
version: '3' services: app: container_name: my-app build: . ports: - '3000:80' volumes: - .:/usr/src/app/ - node_modules:/usr/src/app/node_modules volumes: node_modules:
I use this dockerfile:
FROM node:14 WORKDIR /usr/src/app/ COPY package.json yarn.lock ./ RUN yarn install EXPOSE 80 CMD ["yarn", "dev", "-p", "80"]
This all works perfectly fine, until I try to install a new dependency. I install it locally using
yarn add. This changes the
yarn.lock files. I’m expecting the
RUN yarn install command to run because
COPY package.json yarn.lock ./ is no longer cached. This works, when I run
docker-compose up --build I get visual confirmation that
yarn install runs and installs new packages. However, when I confirm that it is installed and therefore stored in the
node_modules volume I find that it is not. I checked both the volume directory and the directory in the running docker container, both of them don’t contain the package.
I find this very odd. The way I fix this now is by running
docker exec -it my-app yarn install. This does install the package in my volume. I can also confirm that the volume is mounted correctly by running
docker exec -it my-app ls node_modules | grep [module], and running the application is also successful after this.
I can’t think of a valid reason why this is happening. I’ve looked at numerous articles online that use a very similar configuration. The reason I’m using a named volume for node_modules is so that I could debug it more easily, it was anonymous before with the same issues. My understanding is that the volumes docker-compose creates are also available when the image gets built, but that might be incorrect.
To summarize, I want to run a nextjs development server in a docker container. When I build the image, I want to install all the packages in a volume.
docker-compose up --build does run
yarn install but doesn’t install the packages in my volume. Why not? Is there a better way to do this?
Source: Docker Questions