Home > database >  How can I use a bind mount in docker-compose and still preserve node_modules?
How can I use a bind mount in docker-compose and still preserve node_modules?

Time:06-26

I am trying to build and run an image based on this docker course. The goal is to have a bind mount that allows me to sync source code changes with the running container, but also to preserve the node_modules directory of the image that is created during the image build. The video recommends using the following:

services:
  node-app:
    build:
      context: .
      args:
        - NODE_ENV=development
    environment:
      - NODE_ENV=development
    volumes:
      - ./:/app:ro
      - /app/node_modules
    command: npm run dev

However, when I run docker-compose up --build, it gives me this error:

Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error mounting "/var/lib/docker/volumes/4af0c23016b50a7ea3ce1dffe0af69fcb2a0e1b18f2444c9d6b02bb31e557fe3/_data" to rootfs at "/app/node_modules": mkdir /var/lib/docker/overlay2/8af3fad3cb0cd9ac95e1dae61c88560e37630870be29002625e6112efa1f0f8c/merged/app/node_modules: read-only file system: unknown

Which appears to be because I am overlaying a writable volume on a read only volume, but I have no idea how to solve that issue.

I have tried using a src sub-directory to house my index.js on a different level as node_modules, but that starts to feel like spaghetti, and I don't want to have to set up a bunch of environment variables in package.json or the Dockerfile just to have a reusable setup. (I also prefer being able to just use node index.js for the production version of the image.)

I really just want to know a proper way to do this without any headache, something simple and ergonomic.

If I am just overthinking this, or if the subdirectory is the best way, that is fine too, I just can't seem to find good solutions, or any standard ways of doing this.

Also, if it matters, I am on linux.

Supremely grateful for any and all answers, as I am sure I will learn something from all of them.

Thanks!

EDIT: I forgot to mention that I do not want to have node_modules in my development directory, just in the container.

CodePudding user response:

Mount requires that a directory exists on the parent filesystem where the mount is performed. So you can't do both, a read-only filesystem, and no node_modules folder in that filesystem.

The solution is to either:

  • Remove the :ro from the parent folder volume, which will result in a node_modules folder being created in there on container start.
  • Creating the node_modules folder in the development directory.

The folder can (or will) be empty, and you'll use the contents of the image, this is just a requirement for the mount syscall.

  • Related