Module 11: DevOps & Deployment

Master DevOps practices and deployment strategies including Docker containerization, CI/CD pipelines, cloud deployment, and monitoring for Node.js applications.

Back to Course|6.5 hours|Advanced

DevOps & Deployment

Master DevOps practices and deployment strategies including Docker containerization, CI/CD pipelines, cloud deployment, and monitoring for Node.js applications.

Progress: 0/4 topics completed0%

Select Topics Overview

Docker Containerization

Learn Docker containerization for Node.js applications including multi-stage builds, optimization, and best practices.

Content by: Praveen Kumar

MERN Stack Developer

Connect

Docker Fundamentals

Docker allows you to package applications and their dependencies into lightweight, portable containers that can run consistently across different environments.

Basic Dockerfile

Code Example
# Basic Dockerfile for Node.js
FROM node:18-alpine

# Set working directory
WORKDIR /app

# Copy package files
COPY package*.json ./

# Install dependencies
RUN npm ci --only=production

# Copy application code
COPY . .

# Expose port
EXPOSE 3000

# Start application
CMD ["npm", "start"]
Swipe to see more code

Multi-stage Build

Code Example
# Multi-stage Dockerfile for optimization
# Build stage
FROM node:18-alpine AS builder

WORKDIR /app
COPY package*.json ./
RUN npm ci

COPY . .
RUN npm run build

# Production stage
FROM node:18-alpine AS production

# Create non-root user
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001

WORKDIR /app

# Copy built application
COPY --from=builder --chown=nextjs:nodejs /app/dist ./dist
COPY --from=builder --chown=nextjs:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=nextjs:nodejs /app/package*.json ./

USER nextjs

EXPOSE 3000

CMD ["node", "dist/index.js"]
Swipe to see more code

Docker Compose

Code Example
# docker-compose.yml for full stack application
version: '3.8'

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://user:password@db:5432/myapp
      - REDIS_URL=redis://redis:6379
    depends_on:
      - db
      - redis
    volumes:
      - ./logs:/app/logs
    restart: unless-stopped

  db:
    image: postgres:15-alpine
    environment:
      - POSTGRES_DB=myapp
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=password
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"
    restart: unless-stopped

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    restart: unless-stopped

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - app
    restart: unless-stopped

volumes:
  postgres_data:
  redis_data:
Swipe to see more code

Docker Best Practices

  • Use multi-stage builds to reduce image size
  • Use .dockerignore to exclude unnecessary files
  • Run as non-root user for security
  • Use specific base image tags
  • Minimize layers and combine RUN commands
  • Use health checks for container monitoring

Mini-Project: Production Docker Setup

Code Example
# Complete production Docker setup
# Dockerfile
FROM node:18-alpine AS base

# Install dependencies only when needed
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app

COPY package.json package-lock.json* ./
RUN npm ci --only=production

# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

# Build the application
RUN npm run build

# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app

ENV NODE_ENV production

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

EXPOSE 3000

ENV PORT 3000
ENV HOSTNAME "0.0.0.0"

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

# .dockerignore
node_modules
npm-debug.log
.next
.git
.env.local
.env.development.local
.env.test.local
.env.production.local
README.md
Dockerfile
.dockerignore

# docker-compose.prod.yml
version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://user:password@db:5432/myapp
    depends_on:
      - db
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  db:
    image: postgres:15-alpine
    environment:
      - POSTGRES_DB=myapp
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=password
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped

volumes:
  postgres_data:
Swipe to see more code

🎯 Practice Exercise

Test your understanding of this topic:

Additional Resources

📚 Recommended Reading

  • Docker Best Practices Guide
  • CI/CD Pipeline Design
  • Cloud Deployment Strategies
  • Monitoring and Observability

🌐 Online Resources

  • Docker Tutorial for Node.js
  • GitHub Actions Guide
  • AWS Deployment Tutorial
  • Prometheus and Grafana Setup

Ready for the Next Module?

Continue your learning journey and master the next set of concepts.

Continue to Module 12