'docker-compose create volume of my app folder and run node command in it

Docker beginner here.

I am trying to set up docker for local development. My ultimate goal is to be able to use "vite" to do hot module reloading development server.

Here's what I am trying:

#docker-compose.yml
version: '3.8'
services:
  mpvdb:
    image: mysql:5.7
    restart: unless-stopped
    environment:
      - MYSQL_ROOT_PASSWORD=123456
      - MYSQL_DATABASE=cicd
    ports:
      - 3307:3306
    volumes:
      - db:/var/lib/mysql
      - ./mysql-dump:/docker-entrypoint-initdb.d
  mvpnode:
    image: node:18.1.0
    ports:
      - 4444:4444
    volumes:
      - type: volume
        source: client
        target: /client
    command: sh -c "cd ./client && npm run start"
volumes:
  db:
  client:

Note that I have folder in my repo called client I want to have this folder be accessible to the node container so that if I make a change to it the vite dev server (started via npm run start) will detect changes and do its thing, ultimately serving an app to port 4444.

The issue I am facing is either in my attempt to establish the client volume or in my command script. When I try to run the command and start the server I get the following:

mvpnode_1  | npm ERR! code ENOENT
mvpnode_1  | npm ERR! syscall open
mvpnode_1  | npm ERR! path /client/package.json
mvpnode_1  | npm ERR! errno -2
mvpnode_1  | npm ERR! enoent ENOENT: no such file or directory, open '/client/package.json'
mvpnode_1  | npm ERR! enoent This is related to npm not being able to find a file.
mvpnode_1  | npm ERR! enoent

Firstly, how can I change my yml file to make this work?

Secondly, is my assumption that the container will maintain a connection to the /server folder on my windows filesystem correct? So that if I change the code in the application it will be reflected in the container's volume? Or is this wrong and it caches a copy of the code when I spin up the container? I have found conflicting information about this online.

Thanks!



Solution 1:[1]

I think your issue is that you're using a docker volume. A docker volume is a piece of storage managed by docker. What you usually want when you're doing development with hot reload is a bind mount which lets the container access a part of the host's file system. With hot reload, you make a bind mount to the place where you keep your source code.

If your source code is in a client directory below the directory with the docker-compose file, you can do

version: '3.8'
services:
  mpvdb:
    image: mysql:5.7
    restart: unless-stopped
    environment:
      - MYSQL_ROOT_PASSWORD=123456
      - MYSQL_DATABASE=cicd
    ports:
      - 3307:3306
    volumes:
      - db:/var/lib/mysql
      - ./mysql-dump:/docker-entrypoint-initdb.d
  mvpnode:
    image: node:18.1.0
    ports:
      - 4444:4444
    volumes:
      - ./client:/client
    command: sh -c "cd /client && npm install && npm run start"
volumes:
  db:

You should also add npm install to the commands run on startup, since you need to have the relevant node modules installed before starting the app.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Hans Kilian