CodePark/ questions / Volumes & bind mounts
START PRACTICINGPRACTICE
Backend question · Docker › Volumes & bind mounts

In development you bind mount your project into the container and the app crashes with Cannot find module 'express'. Why, and how is it usually fixed?

services:
  api:
    build: .
    volumes:
      - .:/app

The bind mount hides the image's node_modules. A bind mount puts a folder from your computer (the host) inside the container.

Here is what happens. The image ran npm ci, so it has node_modules inside /app. When you mount the host folder over /app, it hides everything the image had at that path, including node_modules. Then one of two things goes wrong:

  • The host has no node_modules, so the module is missing.
  • The host has node_modules, but they were installed for the host OS. Native modules may not work on Linux in the container.

The usual fix is a second mount just for /app/node_modules, such as the anonymous volume - /app/node_modules. The more specific mount wins for that path. So the container keeps the modules installed in the image, and the rest of the code comes from the host.

Also exclude node_modules in .dockerignore. Compose Watch is a newer alternative. It copies (syncs) changed files into the container instead of using a bind mount.

  • A mount hides the files that the image already had at that path.
  • The bind mount hides the image's node_modules folder.
  • Modules from the host may be built for a different OS.
  • Add a separate volume for /app/node_modules to keep the image's modules.