12.2.2.5 Node Static Serving
A focused guide to Node Static Serving, connecting core concepts with practical Docker and container operations.
Node static serving describes how a Node.js-based frontend application's built output — static HTML, CSS, and JavaScript files — is typically served in production through a dedicated web server like nginx, rather than through Node.js itself, in a multi-stage build that separates the build process from this more efficient serving mechanism.
The Multi-Stage Pattern for Static Frontend Serving
The build stage compiles the frontend application into static files; the final stage uses a lightweight web server to serve them.
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80
The final image contains no Node.js runtime at all, only nginx and the static files the build stage produced.
Why a Dedicated Web Server Outperforms Node.js for This Specific Purpose
A web server like nginx, purpose-built for efficiently serving static files, generally outperforms a Node.js process attempting the same task, while also not requiring the Node.js runtime to be present in the final image at all.
docker images
myapp-node-serving 220MB
myapp-nginx-serving 45MB
Configuring nginx for a Single-Page Application's Routing
A single-page application typically needs nginx configured to redirect all routes to the same index.html, letting client-side routing handle the rest.
location / {
try_files $uri /index.html;
}
COPY nginx.conf /etc/nginx/conf.d/default.conf
Why This Pattern Matters for Frontend Applications Specifically
This pattern applies specifically to frontend applications producing static output — a Node.js backend application, by contrast, genuinely needs the Node.js runtime present to actually execute its server-side logic.
Why Node Static Serving Matters
Recognizing that a static frontend's built output is best served by a dedicated web server, rather than the Node.js runtime that built it, produces a meaningfully smaller, more efficient final image appropriate to this specific, common frontend deployment pattern.