25

I am trying to mount my working node code from my host into a docker container and run it using nodemon using docker-compose. But container doesn't seems to be able to find nodemon. Note: My host machine does not has node or npm installed on it.

Here are the files in the root folder of my project (test). (This is only a rough draft)

Dockerfile

FROM surenderthakran/nodejs:v4
ADD . /test
WORKDIR /test
RUN make install
CMD make run

Makefile

SHELL:=/bin/bash
PWD:=$(shell pwd)
export PATH:= $(PWD)/node_modules/.bin:$(PWD)/bin:$(PATH)
DOCKER:=$(shell grep docker /proc/1/cgroup)

install:
    @echo Running make install......
    @npm config set unsafe-perm true
    @npm install

run:
    @echo Running make run......
# Check if we are inside docker container
ifdef DOCKER
    @echo We are dockerized!! :D
    @nodemon index.js
else
    @nodemon index.js
endif

.PHONY: install run

docker-compose.yml

app:
    build: .
    command: make run
    volumes:
        - .:/test
    environment:
        NODE_ENV: dev
    ports:
        - "17883:17883"
        - "17884:17884"

package.json

{
  "name": "test",
  "version": "1.0.0",
  "description": "test",
  "main": "index.js",
  "dependencies": {
    "express": "^4.13.3",
    "nodemon": "^1.8.0"
  },
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "api",
    "nodejs",
    "express"
  ],
  "author": "test",
  "license": "ISC"
}

index.js

'use strict';

var express = require('express');

I build my image using docker-compose build. It finishes successfully. But when I try to run it using docker-compose up, I get:

Creating test_app_1...
Attaching to test_app_1
app_1 | Running make run......
app_1 | We are dockerized!! :D
app_1 | /bin/bash: nodemon: command not found
app_1 | make: *** [run] Error 127
test_app_1 exited with code 2
Gracefully stopping... (press Ctrl+C again to force)

Can anyone please advice?

Note: The Dockerfile for my base image surenderthakran/nodejs:v4 can be found here: https://github.com/surenderthakran/dockerfile_nodejs/blob/master/Dockerfile

5
  • If you try interactively, does it work? Commented Nov 12, 2015 at 9:40
  • 1
    @allprog Yes it works interactively Commented Nov 12, 2015 at 10:13
  • 1
    Sounds like a PATH issue - try using the full path to nodemon: /path/to/nodemon Commented Nov 12, 2015 at 12:17
  • @ChrisMcKinnel the issue has been resolved. Feel free to suggest a better solution as mine is not very elegant. Thanks Commented Nov 12, 2015 at 12:34
  • @allprog the issue has been resolved. Feel free to suggest a better solution as mine is not very elegant. Thanks Commented Nov 12, 2015 at 12:34

5 Answers 5

21

The issue has been resolved. The issue boiled down to me not having node_modules in the mounted volume.

Basically, while doing docker-compose build the image was build correctly with the actual code being added to the image and creating the node_modules folder by npm install in the project root. But with docker-compose up the code was being mounted in the project root and it was overriding the earlier added code including the newly created node_modules folder.

So as a solution I compromised to install nodejs on my host and do a npm install on my host. So when the code my being mounted I still got my node_modules folder in my project root because it was also getting mounted from my host.

Not a very elegant solution but since it is a development setup I am ready for the compromise. On production I would be setting up using docker build and docker run and won't be using nodemon anyways.

If anyone can suggest me a better solution I will be greatful.

Thanks!!

Sign up to request clarification or add additional context in comments.

2 Comments

I'm not that familiar with npm/node, but I think you could install them to a different url outside of the project root using npm install -g and then link to them with npm link instead of installing them again locally? Another alternative might be to install them to a custom path in the container using npm config set prefix, then have a symlink in your project directory that points ./node_modules at that directory. I think that will work with both add and volumes.
Bullseye solution.
5

I believe you should use a preinstall script in your package.json.

So, in the script section, just add script:

 "scritpts": {
     "preinstall": "npm i nodemon -g",
     "start": "nodemon app.js",
 }

And you should good to go :)

1 Comment

Maybe you'll need to RUN npm set unsafe-perm true before RUN npm install.
5

You need to set the node_modules as a mounted volume in the docker container.

e.g

docker-compose.yml

app:
build: .
command: make run
volumes:
    - .:/test
    - /test/node_modules
environment:
    NODE_ENV: dev
ports:
    - "17883:17883"
    - "17884:17884"

1 Comment

This is the perfect solution, thanks Ricardo
3

I've figured out how to do this without a Dockerfile, in case that's useful to anyone...

You can run multiple commands in the docker-compose.yml command line by using sh -c.

  my-server:
    image: node:18-alpine
    build: .
    volumes:
      - .:/usr/src/app
      - /usr/src/app/node_modules
    working_dir: /usr/src/app
    ports:
      - "3100:3100"
    command: sh -c "npm install -g nodemon && npm install && npm run dev "
    environment:
      NODE_ENV: development
      PORT: 3100

1 Comment

hey it's perfecto ! Here is my Dockerfile FROM node:14 WORKDIR /app COPY package.json /app/ RUN npm install -g nodemon RUN npm install COPY . /app EXPOSE 3000 CMD ["npm", "run", "dev"]
1

Pretty late for an answer. But you could use something called as named volumes to mount your node_modules in the docker volumes space. That way it would hide your bind mount.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.