Back to Blog
·8 min

Docker for Web Developers: Complete Containerization Guide

Docker has become an essential tool for web development. It ensures your application runs identically on every machine — your laptop, your team members' computers, your CI/CD pipeline, and production. For web developers building with Next.js, Node.js, and PostgreSQL, Docker eliminates the "it works on my machine" problem.

This guide covers Docker fundamentals for web developers, multi-stage builds, docker-compose for full-stack applications, and production deployment best practices.

Why Docker for Web Development

Docker provides three critical benefits for web developers:

  • Consistency: The same environment everywhere — no more dependency version mismatches
  • Isolation: Each service runs in its own container without conflicts
  • Reproducibility: New team members can start developing in minutes, not hours

Dockerfile for Next.js Applications

# Dockerfile — Multi-stage build for Next.js

# Stage 1: Install dependencies
FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --only=production

# Stage 2: Build the application
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ENV NEXT_TELEMETRY_DISABLED=1
RUN npm run build

# Stage 3: Production runner
FROM node:20-alpine AS runner
WORKDIR /app

ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1

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
CMD ["node", "server.js"]

Docker Compose for Full-Stack Applications

# docker-compose.yml
version: '3.8'

services:
  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: myapp
      POSTGRES_PASSWORD: myapp_password
      POSTGRES_DB: myapp_dev
    ports:
      - '5432:5432'
    volumes:
      - postgres_data:/var/lib/postgresql/data

  app:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - '3000:3000'
    environment:
      DATABASE_URL: postgresql://myapp:myapp_password@postgres:5432/myapp_dev
      NEXTAUTH_SECRET: your-secret-key
      NEXTAUTH_URL: http://localhost:3000
    depends_on:
      - postgres
    volumes:
      - ./src:/app/src
      - ./public:/app/public

  # Optional: Stripe webhook forwarding for local development
  stripe-webhook:
    image: stripe/stripe-cli
    command: listen --forward-to app:3000/api/webhooks/stripe
    environment:
      STRIPE_API_KEY: sk_test_your_key

volumes:
  postgres_data:

Docker Development Workflow

Start your development environment with a single command:

# Start all services
docker compose up -d

# View logs
docker compose logs -f app

# Run database migrations
docker compose exec app npx prisma migrate dev

# Open PostgreSQL shell
docker compose exec postgres psql -U myapp myapp_dev

# Stop all services
docker compose down

Docker Best Practices

Use .dockerignore to reduce build context

node_modules
.next
.git
.env
.env.local
*.md
Dockerfile
docker-compose.yml

Health checks for production reliability

services:
  app:
    healthcheck:
      test: ['CMD', 'wget', '--no-verbose', '--tries=1', 'http://localhost:3000/api/health']
      interval: 30s
      timeout: 10s
      retries: 3
  postgres:
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U myapp']
      interval: 10s
      timeout: 5s
      retries: 5

Multi-stage builds reduce image size

A properly optimized Next.js Docker image should be under 200MB. Without multi-stage builds, images can easily exceed 1GB.

Environment-specific configurations

# docker-compose.override.yml — Local development overrides
services:
  app:
    volumes:
      - ./src:/app/src  # Hot reload in development
    environment:
      NODE_ENV: development
    command: npm run dev

Deploying with Docker

# Build for production
docker compose -f docker-compose.yml build

# Push to container registry
docker tag myapp:latest registry.example.com/myapp:latest
docker push registry.example.com/myapp:latest

# Deploy on server
ssh myserver "docker pull registry.example.com/myapp:latest && docker compose up -d"

The Bottom Line

Docker is an essential tool for modern web development. A Docker-enabled starter kit ensures your Next.js application runs identically in development, staging, and production. The SaaS Starter Kit includes production-ready Docker configuration with multi-stage builds, docker-compose for full-stack development, and deployment scripts.

Ready to Build?

Get started with our production-ready starter kits and ship your project faster.

Browse Starter Kits