$ -weight: 500;">docker --version
-weight: 500;">docker run hello-world
-weight: 500;">docker --version
-weight: 500;">docker run hello-world
-weight: 500;">docker --version
-weight: 500;">docker run hello-world
-weight: 600;">sudo usermod -aG -weight: 500;">docker $USER
-weight: 600;">sudo usermod -aG -weight: 500;">docker $USER
mkdir my--weight: 500;">docker-app
cd my--weight: 500;">docker-app
-weight: 500;">npm init -y
-weight: 500;">npm -weight: 500;">install express
mkdir my--weight: 500;">docker-app
cd my--weight: 500;">docker-app
-weight: 500;">npm init -y
-weight: 500;">npm -weight: 500;">install express
mkdir my--weight: 500;">docker-app
cd my--weight: 500;">docker-app
-weight: 500;">npm init -y
-weight: 500;">npm -weight: 500;">install express
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000; app.get('/', (req, res) => { res.send(`Hello from Docker! Running on ${process.platform}`);
}); app.listen(PORT, () => { console.log(`App running on http://localhost:${PORT}`);
});
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000; app.get('/', (req, res) => { res.send(`Hello from Docker! Running on ${process.platform}`);
}); app.listen(PORT, () => { console.log(`App running on http://localhost:${PORT}`);
});
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000; app.get('/', (req, res) => { res.send(`Hello from Docker! Running on ${process.platform}`);
}); app.listen(PORT, () => { console.log(`App running on http://localhost:${PORT}`);
});
node app.js
node app.js
node app.js
# Use an official Node runtime as base
FROM node:18-alpine # Set working directory inside container
WORKDIR /app # Copy package files
COPY package*.json ./ # Install dependencies
RUN -weight: 500;">npm -weight: 500;">install # Copy app source
COPY . . # Expose port
EXPOSE 3000 # Run app
CMD ["node", "app.js"]
# Use an official Node runtime as base
FROM node:18-alpine # Set working directory inside container
WORKDIR /app # Copy package files
COPY package*.json ./ # Install dependencies
RUN -weight: 500;">npm -weight: 500;">install # Copy app source
COPY . . # Expose port
EXPOSE 3000 # Run app
CMD ["node", "app.js"]
# Use an official Node runtime as base
FROM node:18-alpine # Set working directory inside container
WORKDIR /app # Copy package files
COPY package*.json ./ # Install dependencies
RUN -weight: 500;">npm -weight: 500;">install # Copy app source
COPY . . # Expose port
EXPOSE 3000 # Run app
CMD ["node", "app.js"]
-weight: 500;">docker build -t my-node-app .
-weight: 500;">docker build -t my-node-app .
-weight: 500;">docker build -t my-node-app .
-weight: 500;">docker run -p 3000:3000 my-node-app
-weight: 500;">docker run -p 3000:3000 my-node-app
-weight: 500;">docker run -p 3000:3000 my-node-app
version: '3.8' services: app: build: . ports: - "3000:3000" volumes: - ./:/app environment: - NODE_ENV=development
version: '3.8' services: app: build: . ports: - "3000:3000" volumes: - ./:/app environment: - NODE_ENV=development
version: '3.8' services: app: build: . ports: - "3000:3000" volumes: - ./:/app environment: - NODE_ENV=development
-weight: 500;">docker-compose up
-weight: 500;">docker-compose up
-weight: 500;">docker-compose up
node_modules
-weight: 500;">npm-debug.log
.-weight: 500;">git
.env
node_modules
-weight: 500;">npm-debug.log
.-weight: 500;">git
.env
node_modules
-weight: 500;">npm-debug.log
.-weight: 500;">git
.env
# Add non-root user
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001 USER nextjs
# Add non-root user
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001 USER nextjs
# Add non-root user
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001 USER nextjs
# Build stage
FROM node:18-alpine as builder
WORKDIR /app
COPY package*.json ./
RUN -weight: 500;">npm -weight: 500;">install
COPY . .
RUN -weight: 500;">npm run build # Production stage
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/package*.json ./
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
EXPOSE 3000
CMD ["node", "dist/index.js"]
# Build stage
FROM node:18-alpine as builder
WORKDIR /app
COPY package*.json ./
RUN -weight: 500;">npm -weight: 500;">install
COPY . .
RUN -weight: 500;">npm run build # Production stage
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/package*.json ./
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
EXPOSE 3000
CMD ["node", "dist/index.js"]
# Build stage
FROM node:18-alpine as builder
WORKDIR /app
COPY package*.json ./
RUN -weight: 500;">npm -weight: 500;">install
COPY . .
RUN -weight: 500;">npm run build # Production stage
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/package*.json ./
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
EXPOSE 3000
CMD ["node", "dist/index.js"]
-weight: 500;">docker tag my-node-app your-dockerhub/my-node-app:latest
-weight: 500;">docker push your-dockerhub/my-node-app:latest
-weight: 500;">docker tag my-node-app your-dockerhub/my-node-app:latest
-weight: 500;">docker push your-dockerhub/my-node-app:latest
-weight: 500;">docker tag my-node-app your-dockerhub/my-node-app:latest
-weight: 500;">docker push your-dockerhub/my-node-app:latest - “It works on my machine.”
- Different OS, versions, dependencies = chaos.
- Devs spend hours debugging environment issues. - Everything your app needs is defined in code.
- Share a single Dockerfile and -weight: 500;">docker-compose.yml, and everyone runs the same thing. - FROM: Start from a lightweight Node 18 image.
- WORKDIR: Set where the app lives inside the container.
- COPY: Bring in package.json first (Docker caches layers — this speeds up rebuilds).
- RUN: Install deps.
- COPY . .: Copy the rest of your code.
- EXPOSE: Document that the container listens on port 3000.
- CMD: Command to run when container starts. - -t my-node-app: Tags the image with a name.
- .: Build from current directory. - -p 3000:3000: Maps host port 3000 → container port 3000. - Builds the image (if needed).
- Mounts your current directory into /app in the container.
- Any code change is reflected immediately — no rebuild. - Wrote a simple app.
- Containerized it with a Dockerfile.
- Ran it locally.
- Set up hot-reloading with -weight: 500;">docker-compose.
- Avoided common traps.