Dockerfile Optimizer for Node.js
Analyze your Dockerfile for Node.js best practices. Get suggestions for smaller images, better security, and faster builds.
Paste Your Dockerfile
Dockerfile Best Practices for Node.js
Use Alpine Images
Alpine-based images (node:20-alpine) are ~100MB vs ~1GB for full images. They include musl libc instead of glibc, which works for most Node.js applications. If you need native dependencies, consider node:20-slim (Debian-based, ~200MB).
Multi-Stage Builds
Use multi-stage builds to separate build dependencies from runtime. This keeps your final image small by excluding TypeScript, build tools, and dev dependencies.
# Build stage FROM node:20-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # Production stage FROM node:20-alpine WORKDIR /app COPY --from=builder /app/dist ./dist COPY package*.json ./ RUN npm ci --omit=dev CMD ["node", "dist/server.js"]
Layer Caching
Docker caches layers top-to-bottom. Copy package.json first, install dependencies, then copy source files. This way, npm install is cached when only source code changes.
Security Best Practices
- Non-root user: Run as the built-in
nodeuser or create one - Pin versions: Use specific tags like
node:20.10.0-alpine - Use npm ci: For reproducible builds from package-lock.json
- Scan images: Use
docker scoutor Trivy for vulnerabilities
Production Optimizations
- Set
NODE_ENV=productionfor optimized runtime behavior - Use
npm ci --omit=devto exclude dev dependencies - Add healthchecks for container orchestration
- Use
nodedirectly instead ofnpm startfor proper signal handling - Clear npm cache after install to reduce image size
Common Mistakes
- Using
:latesttag (unpredictable builds) - Running as root (security risk)
- Copying all files before npm install (breaks caching)
- Including dev dependencies in production image
- Not setting NODE_ENV=production