We’ll build a simple Node.js app and serve it using Nginx.
Folder Structure
Create this structure:
multi-stage-demo/
├── Dockerfile
├── package.json
├── package-lock.json
├── server.js
Sample Node.js App
📄 package.json
{
"name": "multi-stage-demo",
"version": "1.0.0",
"main": "server.js",
"scripts": {
"build": "echo 'Build step completed'",
"start": "node server.js"
},
"dependencies": {
"express": "^4.18.2"
}
}
📄 server.js
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Hello from Multi‑Stage Docker Build!');
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
Dockerfile — Multi‑Stage Build (⭐ Core Part)
📄 Dockerfile
# -------------------------
# Stage 1: Build stage
# -------------------------
#Start a new image layer, Use the official Node.js version 18 image, Names this stage builder
FROM node:18 AS builder
#Sets the working directory inside the container to /app
WORKDIR /app
#Copies: package.json, From your local machine Into /app inside the container
COPY package*.json ./
#Downloads all dependencies
RUN npm install
#Copies everything from current folder Into /app inside the container
COPY . .
#Builds the application
RUN npm run build
# -------------------------
# Stage 2: Runtime stage
# -------------------------
#Starts a brand new image, Based on Alpine Linux
FROM node:18-alpine
#Sets /app as working directory
WORKDIR /app
# Copy only required files from builder stage
COPY --from=builder /app .
#“This container listens on port 3000”
EXPOSE 3000
#Defines the default command when container starts
CMD ["npm", "start"]
What’s Happening Step by Step
✅ Stage 1: builder
- Uses full Node image
- Installs dependencies
- Runs build command
- Produces app files
✅ Stage 2: final image
- Uses lighter Node Alpine image
- Copies only needed output from Stage 1
- No build tools included
🔍 Key Line Explained
Dockerfile
COPY –from=builder /app .
Show more lines
This copies files from the builder stage into the final image
🔄 Same Demo: WITHOUT vs WITH Multi‑Stage
| Without | With Multi‑Stage |
|---|---|
Single FROM | Multiple FROM |
| Build tools remain | Build tools removed |
| Larger image | Smaller image |
| Slower deploy | Faster deploy |
🔧 Build & Run the Image
Build Docker Image
docker build -t multi-stage-demo .
Run Container
docker run -p 3000:3000 multi-stage-demo
Open Browser
http://localhost:3000
✅ You’ll see:
Hello from Multi‑Stage Docker Build!
