2

Hi I'm trying to dockerize an app im currently working on. It uses nodejs and mariadb. I have some difficulties with figuring out how to make nodemon work.

I tried using --legacy-watch or -L which is the short form but it didn't change the result.

NPM installs all dependecies correct i even get the nodemon text but it doesn't restart the server when i make changes.

Would be gal if anyone could help

package.json:

{
  "name": "nodejs_mariadb_docker_test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node src/index.js",
    "dev": "nodemon -L src/index.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.2",
    "mariadb": "^2.5.5",
    "nodemon": "^2.0.15"
  }
}

Dockerfile for nodejs:

# Specifies the image of your engine
FROM node:16.13.2

# The working directory inside your container
WORKDIR /app

# Get the package.json first to install dependencies
COPY package.json /app

# This will install those dependencies
RUN npm install

# Copy the rest of the app to the working directory
COPY . /app

# Run the container
CMD ["npm", "run", "dev"]

and the docker compose file:

version: "3"
services: 
  node:
    build: .
    container_name: express-api
    ports:
      - "80:8000"
    depends_on: 
      - mysql

  mysql:
    image: mariadb:latest
    ports:
      - "3306:3306"
    environment: 
      MYSQL_ROOT_PASSWORD: "password"
    volumes:
      - mysqldata:/var/lib/mysql
      - ./mysql-dump:/docker-entrypoint-initdb.d
volumes:
    mysqldata: {}
0szi
  • 318
  • 3
  • 14

1 Answers1

2

So the obvious problem is that you do not mount your code into the container. That is why nodemon cannot see any changes, and react to them.

Additionally, it may be more straight forward to develop the application locally and only use docker as a mean to package/ship it.

If you still want to go down this route, I would suggest something like this.

services: 
  express-api:
    build: ./
    # overwrite the prod command
    command: npm run dev
    ports:
      - "80:8000"
    volumes:
      # mount your code folder into the app folder
      - .:/app

# mysql stuff ...

In your dockerfile you can swap the command for the production one, since in development, compose will override it.

FROM node:16.13.2
WORKDIR /app
COPY package.json package-lock.json ./
# use ci to install from the lock file, 
# to avoid suprises in prod
RUN npm ci
COPY . ./
# use the prod command
CMD ["npm", "run", "start"]

This will do a bit of redundant work in development, like copying the code, but it should be OK.

Additionally, you may want to use a .dockerignore to ignore the mysqldump for example. Otherwise, it will be copied into the image, which is probably not desirable.

Also note that through npm ci your dependencies are locked, and won't update automatically. It will also throw errors if your lock file is not in sync with package.json. This is what you want for production. If you develop locally, you can run npm install locally or via docker exec to bump the dependencies, if required. Then you can check if nothing is broken, and be sure that for your prod image it will be fine since it's used from the lock file again.

The Fool
  • 16,715
  • 5
  • 52
  • 86