Node.js Application
Is It recommended to use named volume for node_modules directory in Docker Compose?¶
Yes, using a named volume for node_modules is recommended in Dockerized Node.js applications. However, whether you should use it depends on your needs.
✔ When to Use a Named Volume for node_modules
✅ You want consistency across rebuilds - The dependencies installed inside the container persist even if you rebuild the container. - This avoids issues where node_modules might get overridden by the host machine’s empty directory.
✅ You want to avoid installing dependencies repeatedly - If you don’t use a named volume, node_modules inside the container is lost when the container is removed. - With a named volume, dependencies remain intact between container restarts.
✅ You’re working in a team or CI/CD environment - Ensures everyone uses the same dependencies inside the container, avoiding compatibility issues between local setups.
❌ When NOT to Use a Named Volume for node_modules
🚫 If you're actively developing and modifying dependencies - During development, you often install/remove dependencies (npm install package-name). - With a named volume, the installed dependencies won’t match those inside package.json unless you manually rebuild or run npm install inside the container.
🚫 If you’re using npm ci in a CI/CD pipeline - npm ci installs dependencies fresh every time, ensuring a clean state. - A named volume isn't useful here because dependencies get wiped and reinstalled every build.
What’s the Best Practice?¶
🔹 For production builds: - Yes, using a named volume for node_modules is recommended because it improves performance and consistency.
🔹 For local development: - A bind mount (- .:/usr/src/app) without a named volume is better, so you always use fresh dependencies.
🚀 Recommended docker-compose.yml Setup¶
For Local Development:¶
version: '3.8'
services:
app:
build: .
container_name: express_app
ports:
- "3000:3000"
environment:
- NODE_ENV=development
volumes:
- .:/usr/src/app
- /usr/src/app/node_modules # Ensures node_modules from the container is used
restart: unless-stopped
For Production:¶
version: '3.8'
services:
app:
build: .
container_name: express_app
ports:
- "3000:3000"
environment:
- NODE_ENV=production
volumes:
- node_modules:/usr/src/app/node_modules
restart: unless-stopped
volumes:
node_modules:
Final Verdict:¶
- For development → Use a bind mount but exclude
node_modules - For production → Use a named volume for
node_modules
Bind-Mounting Everything (- .:/usr/src/app)¶
- This overwrites the
/usr/src/appfolder inside the container, making it useless. - This is fine in development but should not be used in production. ✅ Fix: Remove the bind-mounting of the entire project folder
volumes:
- node_modules:/usr/src/app/node_modules
Volume Mapping Issue with node_modules¶
📌 Issue:¶
volumes:
- ./node_modules:/usr/src/app/node_modules
node_modules with your local version. - If node_modules doesn’t exist locally, the app may fail to start. 📌 Fix:¶
Remove the volume mapping unless needed. If you want to cache dependencies, use a named volume:
volumes:
- node_modules:/usr/src/app/node_modules
And define:
volumes:
node_modules:
Fix node_modules Volume Issue¶
📌 Issue:¶
volumes:
- node_modules:/usr/src/app/node_modules
node_modules inside the container is overwritten by an empty volume. 📌 Solution:¶
Instead, use:
volumes:
- .:/usr/src/app
This mounts the entire project folder, including dependencies.
React Frontend with Nginx: Handling node_modules¶
📌 Do You Need to Copy node_modules?¶
Good question! For a React frontend-only application served via Nginx, you do not need to copy node_modules from the build image.
🔹 Why?¶
- Unlike a Node.js + Express app, where
node_modulesis needed to run the backend server, - A React app is purely frontend, and after
npm run build, thebuild/directory contains static files (HTML, JS, CSS). - Nginx only serves static files—it does not execute Node.js code, so
node_modulesis irrelevant.
📌 When Should You Copy node_modules?¶
If the project contains a backend (e.g., Node.js + Express), then you need node_modules for the server to run. In that case, you would: 1. Copy node_modules from the builder stage. 2. Use a Node.js base image in the final stage.
🔹 For Your Current Setup (React + Nginx)¶
✔ No need to copy node_modules—everything required is in /app/build.