BudiBadu Logo
Samplebadu

Dockerfile by Example: Node Application Image

Docker Engine 20.10+

Node.js images benefit from production settings and deterministic installs. This sample code shows how to use NODE_ENV and npm ci.

Code

FROM node:18-alpine

WORKDIR /app

# 1. Set NODE_ENV to production
# Optimizes dependencies and disables dev features
ENV NODE_ENV=production

# 2. Install dependencies
COPY package*.json ./
# npm ci is faster and more reliable than npm install for builds
RUN npm ci --only=production

COPY . .

USER node
CMD ["node", "server.js"]

Explanation

For Node.js applications, setting NODE_ENV=production is a critical optimization. It instructs many libraries (like Express) to cache views, disable verbose error messages, and optimize performance. It also ensures that npm install (or npm ci) skips devDependencies, keeping the image size minimal.

Node.js Docker best practices:

  • Use npm ci instead of npm install for reproducible builds
  • Set NODE_ENV=production for performance and security
  • Run as the built-in node user instead of root
  • Use node:alpine variants for smaller footprint

The command npm ci (Clean Install) is preferred over npm install in CI/CD and Docker environments. It strictly follows the package-lock.json file, ensuring that the exact same dependency versions are installed every time. It also deletes the existing node_modules folder before installation, preventing inconsistencies. This leads to faster, more reliable, and deterministic builds.

Code Breakdown

7
ENV NODE_ENV=production enables production optimizations.
12
npm ci --only=production installs only runtime dependencies.
16
USER node enforces least privilege execution.
1
node:18-alpine is a lightweight base image for Node.js.