areuseriouus.eth
areuseriouus.eth

Reputation: 413

Docker x NodeJS - Issue with node_modules

I'm a web developer who currently is working on a next.js project (it's just a framework to SSR ReactJS). I'm using Docker config on this project and I discovered an issue when I add/remove dependencies. When I add a dependency, build my project and up it with docker-compose, my new dependency isn't added to my Docker image. I have to clean my docker system with docker system prune to reset everything then I could build and up my project. After that, my dependency is added to my Docker container.

I use Dockerfile to configure my image and different docker-compose files to set different configurations depending on my environments. Here is my configuration:

Dockerfile

FROM node:10.13.0-alpine

# SET environment variables
ENV NODE_VERSION 10.13.0
ENV YARN_VERSION 1.12.3

# Install Yarn
RUN apk add --no-cache --virtual .build-deps-yarn curl \
  && curl -fSLO --compressed "https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz" \
  && tar -xzf yarn-v$YARN_VERSION.tar.gz -C /opt/ \
  && ln -snf /opt/yarn-v$YARN_VERSION/bin/yarn /usr/local/bin/yarn \
  && ln -snf /opt/yarn-v$YARN_VERSION/bin/yarnpkg /usr/local/bin/yarnpkg \
  && rm yarn-v$YARN_VERSION.tar.gz \
  && apk del .build-deps-yarn

# Create app directory
RUN mkdir /website
WORKDIR /website
ADD package*.json /website

# Install app dependencies 
RUN yarn install

# Build source files
COPY . /website/
RUN yarn run build

docker-compose.yml (dev env)

version: "3"
services:
  app:
    container_name: website
    build:
      context: .
    ports:
      - "3000:3000"
      - "3332:3332"
      - "9229:9229"
    volumes:
      - /website/node_modules/
      - .:/website
    command: yarn run dev 0.0.0.0 3000
    environment:
      SERVER_URL: https://XXXXXXX.com

Here my commands to run my Docker environment:

docker-compose build --no-cache

docker-compose up

I suppose that something is wrong in my Docker's configuration but I can't catch it. Do you have an idea to help me?

Thanks!

Upvotes: 0

Views: 399

Answers (2)

takacsmark
takacsmark

Reputation: 4431

Your volumes right now are not set up to do what you intend to do. The current set below means that you are overriding the contents of your website directory in the container with your local . directory.

volumes:
  - /website/node_modules/
  - .:/website

I'm sure your intention is to map your local directory into the container first, and then override node_modules with the original contents of the image's node_modules directory, i.e. /website/node_modules/.

Changing the order of your volumes like below should solve the issue.

volumes:
  - .:/website
  - /website/node_modules/

Upvotes: 1

David Maze
David Maze

Reputation: 158758

You are explicitly telling Docker you want this behavior. When you say:

volumes:
  - /website/node_modules/

You are telling Docker you don't want to use the node_modules directory that's baked into the image. Instead, it should create an anonymous volume to hold the node_modules directory (which has some special behavior on its first use) and persist the data there, even if other characteristics like the underlying image change.

That means if you change your package.json and rebuild the image, Docker will keep using the volume version of your node_modules directory. (Similarly, the bind mount of .:/website means everything else in the last half of your Dockerfile is essentially ignored.)

I would remove the volumes: block in this setup to respect the program that's being built in the image. (I'd also suggest moving the command: to a CMD line in the Dockerfile.) Develop and test your application without using Docker, and build and deploy an image once it's essentially working, but not before.

Upvotes: 0

Related Questions