Reputation: 1990
Having simple Node.js docker container
docker-compose.yml:
app:
build: ./dockerfiles/app
volumes:
- /Users/home/work/app:/usr/app
Dockerfile:
FROM node:6.7-slim
COPY package.json /tmp
RUN cd /tmp && npm install
RUN mkdir -p /usr/app
WORKDIR /usr/app
CMD ["node", "./src/app.js"]
What I want to achieve is container where I have package.json and installed node modules (npm install). Part where I copy package.json and install modules inside container is pretty straighforward, but problem occur, when I want to use these node_modules inside linked app. I can't find any way, how to copy /tmp/node_modules into /usr/app/node_modules
Is there any Docker way ho to do that? If not, can I tell my node app to look for node_modules somewhere else than in root directory?
Upvotes: 3
Views: 1971
Reputation: 500
As @schovi has mentioned in order to not override the contents of node_modules within the container and the contents of node_modules within the folder of the host machine, it is necessary to create another internal volume in the docker-compose.yml file:
volumes:
- ${APP_PATH}:/usr/app
- /usr/app/node_modules
Doing that makes it safe to copy the files from /tmp/node_modules into /usr/app/node_modules using this instructions.
FROM node
# Node modules
COPY *.json /tmp/
RUN cd /tmp && yarn
# App
RUN mkdir -p /usr/app
WORKDIR /usr/app
RUN cp -a /tmp/node_modules /usr/app/node_modules
ENV NODE_ENV docker
CMD ["run-node", "src/app.js"]
However, I would create first the app folder and install node_modules directly on it, reducing considerably the cache layers and increasing the building speed.
FROM node:12.8.1 #always mind the version
# Node modules
RUN mkdir -p /usr/app
WORKDIR /usr/app
#Mind that point (workdir)
COPY package*.json .
RUN yarn
ENV NODE_ENV docker
CMD ["run-node", "src/app.js"]
I hope it helps! :D
Upvotes: 1
Reputation: 1990
Thing that helped me is following usage of volumes
volumes:
- ${APP_PATH}:/usr/app
# Empty node_modules directory
- /usr/app/node_modules
Then in Dockerfile:
FROM node
# Node modules
COPY *.json /tmp/
RUN cd /tmp && yarn
ENV NODE_PATH /tmp/node_modules:${NODE_PATH}
# App
RUN mkdir -p /usr/app
WORKDIR /usr/app
ENV NODE_ENV docker
CMD ["run-node", "src/app.js"]
This allow me to have node_modules in another directory and app will look for them there.
Upvotes: 0
Reputation: 54467
You can achieve what you want by changing the CMD
used when starting the container, either in your Dockerfile, or in the docker-compose.yml
file.
Instead of just starting node ./src/app.js
, you want to do two things:
node_modules
over.Using the docker-compose.yml
, I would do the following:
app:
build: ./dockerfiles/app
volumes:
- /Users/home/work/app:/usr/app
command: >
bash -c "
rm -rf /usr/app/node_modules
&& cp -R /tmp/node_modules /usr/app/node_modules
&& node ./src/app.js
"
This will delete the existing node modules on the mapped-in volume, then copy in the ones from container, and then finally starts the node app. This is going to happen every time the container is started.
Upvotes: 1