Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker automatically rerun npm install on package.json change

I'm trying to set up development containers for a node.js project so that my local source files are shared with the guest (so I can dnsmasq wildcard requests to a local domain over port 80, but I guess that's irrelevant to the question). When I make a change locally, the node process in the container is restarted:

Dockerfile:

FROM node:8

# Install app dependencies
RUN npm install -g nodemon
COPY package.json /tmp/package.json
RUN cd /tmp && npm install --production

NODE_PATH=/tmp/node_modules
WORKDIR /app

EXPOSE 8080
EXPOSE 9229

CMD nodemon --inspect index.js

docker-compose.json (truncated):

version: '3.3'
services:
    app:
        build: .
        container_name: 'my-app'
        restart: unless-stopped
        ports:
            - 8080:8080
            - 9229:9229
        volumes:
            - .:/app

Because the node_modules are installed in the Dockerfile, every time I add a package to packages.json, I have to manually re-build the container:

docker-compose stop
docker-compose build
docker-compose up -d

I could set up a watch for this using inotify, but I don't like to stop the entire stack (including other services defined there).

Is it possible to have this logic inside the container, and re-run npm install every time package.json is changed?

like image 232
Redsandro Avatar asked Sep 21 '18 07:09

Redsandro


People also ask

How do I use dockerfile in NPM build?

RUN npm install --production COPY . . CMD [ "node", "server.js" ] To use a file in the build context, the Dockerfile refers to the file specified in an instruction, for example, a COPY instruction. To increase the build’s performance, exclude files and directories by adding a .dockerignore file to the context directory.

How do I add a package to a docker container?

ADD package.json /tmp/package.json RUN cd /tmp && npm install RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app/ To avoid the npm install phase on every docker build just copy those lines and change the ^/opt/app^ to the location your app lives inside the container. That works. Some points though.

How to invalidate NPM install cache in Docker build?

Docker won't rerun npm install command if package.json changes, it caches RUN command result and assumes that same RUN command produces same result. To invalidate cache you should run docker build with --no-cache flag, or change the RUN command somehow.

What is package JSON in NPM?

Package.json File mainly used by NPM to know all the information about your Node.JS Project This command will guide you through all the common items about your projects like name, version, dependencies etc and Wherever possible suggests default values as you can see in the below GIF.


1 Answers

Is it possible to have this logic inside the container, and re-run npm install every time package.json is changed?

It is not fully clear to me, if your changes in package.json are done on host or in docker container in /tmp/ directory. I guess you modify a file on host since you have other project files there.

If you modify package.json in other location than /tmp/ in your container, you need to manually copy new version of package.json to /tmp in container

docker cp "location/of/package.json" "containername":/tmp/

then you just enter the container and install dependencies.

docker exec -it containername bash
cd /tmp/
npm install

Is it possible to have this logic inside the container, and re-run npm install every time package.json is changed?

You could pass logic described above to simple bash script. Then you can run some watcher (for example nodemon) to observe package.json and run the script after file change. Maybe it would be also good idea to pass big delay so it doesn't try to install a module before you even type full name of it. But in most situations I guess you just use npm command instead of typing name of the module manually.

like image 188
Teukros Avatar answered Nov 15 '22 08:11

Teukros