I'm new to Docker and Node.js and I'm trying to set up a Node.js application using Docker. I prefer using Docker over nvm
to manage my Node.js version. Here's the issue I'm facing:
Initial Dockerfile Setup:
Dockerfile
in my project directory with the following content:
Dockerfile FROM node:14 USER node WORKDIR /app
-v ${PWD}:/app
.docker exec
.npm init --yes && npm i mongoose
, which created node_modules
both in the container and in my local repository.Modified Dockerfile:
Dockerfile
to perform npm install
, expose ports, and add other necessary commands as I proceeded. This setup worked fine, but it left a node_modules
folder in my local directory.npm init
and npm install
, I wrote a package.json
file directly.Dockerfile
with FROM
, WORKDIR
, COPY
, and EXPOSE
. I didn't include the CMD
as there's no JS file to run yet.node_modules
folder wasn't created in the directory. I suspect this is due to mounting the volume with -v ${PWD}:/app
.How can I properly set up my Node.js application with Docker so that the node_modules
folder is created and used inside the container without it being stored locally?
Thank you for your help!
Initial Dockerfile Setup:
Dockerfile
with the following content:
FROM node:14
USER node
WORKDIR /app
docker build -t my-node-app .
docker run -v ${PWD}:/app -it my-node-app
docker exec -it <container_id> /bin/sh
npm init --yes && npm i mongoose
This created a node_modules
folder both in the container and in my local directory.Modified Dockerfile:
Dockerfile
to:
FROM node:14
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "index.js"]
node_modules
folder was still present in my local directory due to the volume mapping.Alternative Approach:
package.json
file directly with the required dependencies.Dockerfile
:
FROM node:14
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "index.js"]
docker build -t my-node-app .
docker run -v ${PWD}:/app -it my-node-app
node_modules
folder was not created in my local directory, but it also wasn't available in the container.I expected the node_modules
folder to be created and used inside the Docker container without being present in my local directory. This way, I can manage dependencies within the container, keeping my local workspace clean. I am looking for a solution to achieve this.
You're launching your container with:
docker run -v ${PWD}:/app -it my-node-app
This means that you're replacing the entire contents of the /app
folder in the container with what appears in your current working directory on the host.
This will not be conducive to having just the source files mapped (e.g. /app/app.js
) but somehow not mapping the node_modules
folder (i.e.: /app/node_modules
), because the node_modules
folder is within the folder that you have mounted to the host.
Instead, I suggest restructuring your folders so that the source files you want to map between host and container are their own folder, and then mount only that source folder.
This should be fine because modifying package.json will require a new npm install
within the container whereas source .js file changes can be picked up on the fly. Especially if you want to use nodemon
to automatically pick up changes.
Old structure:
│ app.js
│ package-lock.json
│ package.json
│
└───node_modules
│ .package-lock.json
New structure:
│ package-lock.json
│ package.json
│
├───node_modules
│ .package-lock.json
│
└───src
app.js
Launch like this:
docker run -v ${PWD}/src:/app/src -it my-node-app
Of course, you will have to change your main
property in your package.json
to reflect the new location of the source files. For example:
From:
"main": "app.js"
To:
"main": "src/app.js"