Skip to main content

Documentation Index

Fetch the complete documentation index at: https://asyncfunc.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

Docker Deployment Guide

This comprehensive guide covers everything you need to know about deploying DeepWikiOpen using Docker, from basic setups to production-grade deployments.

Table of Contents

Prerequisites

Before you begin, ensure you have the following installed:
  • Docker (version 20.10+)
  • Docker Compose (version 2.0+)
  • Git (for cloning repositories)

Installation Verification

# Check Docker version
docker --version
docker-compose --version

# Verify Docker is running
docker info

Quick Start with Pre-built Images

Using GitHub Container Registry

DeepWikiOpen provides pre-built images through GitHub Container Registry (GHCR). This is the fastest way to get started.
# Pull the latest image
docker pull ghcr.io/your-org/deepwikiopen:latest

# Run a simple container
docker run -d \
  --name deepwikiopen \
  -p 3000:3000 \
  -e NODE_ENV=production \
  ghcr.io/your-org/deepwikiopen:latest

Available Image Tags

TagDescriptionUse Case
latestLatest stable releaseProduction
developDevelopment branchTesting
v1.2.3Specific versionProduction pinning
slimMinimal image sizeResource-constrained environments

Basic Docker Run Command

docker run -d \
  --name deepwikiopen-app \
  --restart unless-stopped \
  -p 3000:3000 \
  -e DATABASE_URL="postgresql://user:pass@host:5432/db" \
  -e JWT_SECRET="your-secret-key" \
  -e REDIS_URL="redis://redis:6379" \
  -v deepwikiopen-data:/app/data \
  ghcr.io/your-org/deepwikiopen:latest

Building Custom Images

Dockerfile Explanation

Here’s a production-ready Dockerfile with explanations:
# Use Node.js LTS Alpine for smaller image size
FROM node:18-alpine AS base

# Install system dependencies
RUN apk add --no-cache \
    python3 \
    make \
    g++ \
    cairo-dev \
    jpeg-dev \
    pango-dev \
    musl-dev \
    giflib-dev \
    pixman-dev \
    pangomm-dev \
    libjpeg-turbo-dev \
    freetype-dev

# Set working directory
WORKDIR /app

# Copy package files
COPY package*.json ./
COPY yarn.lock ./

# Install dependencies
FROM base AS dependencies
RUN npm ci --only=production --frozen-lockfile

# Development dependencies for building
FROM base AS dev-dependencies
RUN npm ci --frozen-lockfile

# Build stage
FROM dev-dependencies AS build
COPY . .
RUN npm run build
RUN npm run test:unit

# Production stage
FROM base AS production

# Create non-root user for security
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nextjs -u 1001

# Copy production dependencies
COPY --from=dependencies /app/node_modules ./node_modules

# Copy built application
COPY --from=build --chown=nextjs:nodejs /app/.next ./.next
COPY --from=build --chown=nextjs:nodejs /app/public ./public
COPY --from=build --chown=nextjs:nodejs /app/package.json ./package.json

# Create data directory
RUN mkdir -p /app/data && chown -R nextjs:nodejs /app/data

# Switch to non-root user
USER nextjs

# Expose port
EXPOSE 3000

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:3000/api/health || exit 1

# Start the application
CMD ["npm", "start"]

Building the Image

# Build with default tag
docker build -t deepwikiopen:local .

# Build with specific tag and build args
docker build \
  --build-arg NODE_ENV=production \
  --build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') \
  -t deepwikiopen:v1.0.0 .

# Multi-platform build
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t deepwikiopen:multi-arch \
  --push .

Optimized Development Dockerfile

FROM node:18-alpine AS development

# Install development tools
RUN apk add --no-cache \
    git \
    curl \
    vim

WORKDIR /app

# Copy package files
COPY package*.json ./
RUN npm install

# Copy source code
COPY . .

# Expose port and start dev server
EXPOSE 3000
CMD ["npm", "run", "dev"]

Docker Compose Setup

Complete Production Setup

# docker-compose.yml
version: '3.8'

services:
  # Main application
  app:
    image: ghcr.io/your-org/deepwikiopen:latest
    container_name: deepwikiopen-app
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
      - REDIS_URL=redis://redis:6379
      - JWT_SECRET=${JWT_SECRET}
      - NEXTAUTH_URL=${NEXTAUTH_URL}
      - NEXTAUTH_SECRET=${NEXTAUTH_SECRET}
    volumes:
      - app-data:/app/data
      - app-logs:/app/logs
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    networks:
      - deepwikiopen-network
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  # PostgreSQL database
  postgres:
    image: postgres:15-alpine
    container_name: deepwikiopen-postgres
    restart: unless-stopped
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=${POSTGRES_DB}
      - POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=C --lc-ctype=C
    volumes:
      - postgres-data:/var/lib/postgresql/data
      - ./docker/postgres/init:/docker-entrypoint-initdb.d
    ports:
      - "5432:5432"
    networks:
      - deepwikiopen-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

  # Redis cache
  redis:
    image: redis:7-alpine
    container_name: deepwikiopen-redis
    restart: unless-stopped
    command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
    volumes:
      - redis-data:/data
      - ./docker/redis/redis.conf:/usr/local/etc/redis/redis.conf
    ports:
      - "6379:6379"
    networks:
      - deepwikiopen-network
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 3s
      retries: 3

  # Elasticsearch for search
  elasticsearch:
    image: elasticsearch:8.8.0
    container_name: deepwikiopen-elasticsearch
    restart: unless-stopped
    environment:
      - discovery.type=single-node
      - ES_JAVA_OPTS=-Xms512m -Xmx512m
      - xpack.security.enabled=false
    volumes:
      - elasticsearch-data:/usr/share/elasticsearch/data
    ports:
      - "9200:9200"
    networks:
      - deepwikiopen-network
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:9200/_cluster/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  # Nginx reverse proxy
  nginx:
    image: nginx:alpine
    container_name: deepwikiopen-nginx
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./docker/nginx/conf.d:/etc/nginx/conf.d
      - ./docker/ssl:/etc/nginx/ssl
      - nginx-logs:/var/log/nginx
    depends_on:
      - app
    networks:
      - deepwikiopen-network

  # Monitoring with Prometheus
  prometheus:
    image: prom/prometheus:latest
    container_name: deepwikiopen-prometheus
    restart: unless-stopped
    ports:
      - "9090:9090"
    volumes:
      - ./docker/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus-data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'
    networks:
      - deepwikiopen-network

  # Grafana for visualization
  grafana:
    image: grafana/grafana:latest
    container_name: deepwikiopen-grafana
    restart: unless-stopped
    ports:
      - "3001:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
    volumes:
      - grafana-data:/var/lib/grafana
      - ./docker/grafana/provisioning:/etc/grafana/provisioning
    networks:
      - deepwikiopen-network

volumes:
  app-data:
    driver: local
  app-logs:
    driver: local
  postgres-data:
    driver: local
  redis-data:
    driver: local
  elasticsearch-data:
    driver: local
  nginx-logs:
    driver: local
  prometheus-data:
    driver: local
  grafana-data:
    driver: local

networks:
  deepwikiopen-network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/16

Development Compose Setup

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

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile.dev
    container_name: deepwikiopen-dev
    ports:
      - "3000:3000"
      - "9229:9229" # Node.js debugger
    environment:
      - NODE_ENV=development
      - DATABASE_URL=postgresql://postgres:password@postgres:5432/deepwikiopen_dev
      - REDIS_URL=redis://redis:6379
    volumes:
      - .:/app
      - /app/node_modules
      - dev-logs:/app/logs
    depends_on:
      - postgres
      - redis
    networks:
      - dev-network
    command: npm run dev

  postgres:
    image: postgres:15-alpine
    container_name: deepwikiopen-postgres-dev
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=deepwikiopen_dev
    volumes:
      - postgres-dev-data:/var/lib/postgresql/data
    ports:
      - "5432:5432"
    networks:
      - dev-network

  redis:
    image: redis:7-alpine
    container_name: deepwikiopen-redis-dev
    ports:
      - "6379:6379"
    networks:
      - dev-network

volumes:
  postgres-dev-data:
  dev-logs:

networks:
  dev-network:
    driver: bridge

Environment Configuration

Environment Variables Structure

Create a comprehensive .env file:
# .env
# Application Settings
NODE_ENV=production
PORT=3000
APP_URL=https://your-domain.com
APP_NAME="DeepWikiOpen"

# Database Configuration
DATABASE_URL=postgresql://username:password@postgres:5432/deepwikiopen
DB_HOST=postgres
DB_PORT=5432
DB_NAME=deepwikiopen
DB_USER=username
DB_PASSWORD=secure_password

# Redis Configuration
REDIS_URL=redis://redis:6379
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=redis_password

# Authentication
JWT_SECRET=your-super-secret-jwt-key-change-this
NEXTAUTH_URL=https://your-domain.com
NEXTAUTH_SECRET=another-super-secret-key

# OAuth Providers
GITHUB_CLIENT_ID=your_github_client_id
GITHUB_CLIENT_SECRET=your_github_client_secret
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret

# Email Configuration
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your-email@gmail.com
SMTP_PASS=your-app-password

# Storage Configuration
AWS_ACCESS_KEY_ID=your_access_key
AWS_SECRET_ACCESS_KEY=your_secret_key
AWS_REGION=us-east-1
S3_BUCKET_NAME=your-s3-bucket

# Monitoring
SENTRY_DSN=https://your-sentry-dsn
NEW_RELIC_LICENSE_KEY=your-new-relic-key

# Security
CORS_ORIGIN=https://your-domain.com
RATE_LIMIT_MAX=100
RATE_LIMIT_WINDOW_MS=900000

# Feature Flags
ENABLE_SEARCH=true
ENABLE_ANALYTICS=true
ENABLE_NOTIFICATIONS=true

Environment Files for Different Stages

# .env.local (development)
NODE_ENV=development
DATABASE_URL=postgresql://postgres:password@localhost:5432/deepwikiopen_dev
REDIS_URL=redis://localhost:6379
JWT_SECRET=dev-secret

# .env.staging
NODE_ENV=staging
DATABASE_URL=postgresql://user:pass@staging-db:5432/deepwikiopen_staging
REDIS_URL=redis://staging-redis:6379

# .env.production
NODE_ENV=production
DATABASE_URL=postgresql://user:pass@prod-db:5432/deepwikiopen
REDIS_URL=redis://prod-redis:6379

Docker Compose Environment Override

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

services:
  app:
    environment:
      - DEBUG=true
      - LOG_LEVEL=debug
    volumes:
      - ./logs:/app/logs

Volume Mounts and Data Persistence

Volume Types and Use Cases

# Named volumes (recommended for production)
volumes:
  # Database data persistence
  postgres-data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /opt/deepwikiopen/postgres

  # Application data
  app-data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /opt/deepwikiopen/data

  # Logs
  app-logs:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /opt/deepwikiopen/logs

  # Backups
  backup-data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /opt/deepwikiopen/backups

Bind Mounts for Development

services:
  app:
    volumes:
      # Source code (development)
      - ./src:/app/src
      - ./public:/app/public
      - ./package.json:/app/package.json
      
      # Configuration files
      - ./config:/app/config
      - ./docker/app/entrypoint.sh:/app/entrypoint.sh
      
      # Exclude node_modules
      - /app/node_modules

NFS Volumes for Multi-Host Setup

volumes:
  shared-data:
    driver: local
    driver_opts:
      type: nfs
      o: addr=nfs.example.com,rw
      device: ":/path/to/shared/data"

Volume Backup Strategy

# Backup script
#!/bin/bash

# Create backup directory
mkdir -p /backups/$(date +%Y%m%d)

# Backup PostgreSQL
docker exec deepwikiopen-postgres pg_dump -U postgres deepwikiopen > \
  /backups/$(date +%Y%m%d)/postgres-backup.sql

# Backup volumes
docker run --rm \
  -v deepwikiopen_postgres-data:/source \
  -v /backups/$(date +%Y%m%d):/backup \
  alpine tar czf /backup/postgres-data.tar.gz -C /source .

docker run --rm \
  -v deepwikiopen_app-data:/source \
  -v /backups/$(date +%Y%m%d):/backup \
  alpine tar czf /backup/app-data.tar.gz -C /source .

Container Networking

Custom Bridge Network

networks:
  deepwikiopen-network:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.20.0.0/16
          gateway: 172.20.0.1

Service Discovery

services:
  app:
    networks:
      deepwikiopen-network:
        aliases:
          - webapp
          - api
    
  postgres:
    networks:
      deepwikiopen-network:
        aliases:
          - database
          - db

Port Configuration

services:
  # Internal communication only
  app-internal:
    expose:
      - "3000"
    networks:
      - internal

  # External access
  app-external:
    ports:
      - "80:3000"      # HTTP
      - "443:3000"     # HTTPS
      - "3000:3000"    # Direct access
    networks:
      - external

networks:
  internal:
    driver: bridge
    internal: true
  external:
    driver: bridge

Network Security

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

services:
  app:
    networks:
      - frontend
      - backend

  postgres:
    networks:
      - backend
    # No external ports exposed

  redis:
    networks:
      - backend
    # No external ports exposed

  nginx:
    networks:
      - frontend
    ports:
      - "80:80"
      - "443:443"

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    internal: true

Health Checks and Monitoring

Application Health Checks

# Dockerfile health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:3000/api/health || exit 1
# Docker Compose health checks
services:
  app:
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy

Custom Health Check Endpoint

// pages/api/health.js
export default function handler(req, res) {
  const checks = {
    status: 'ok',
    timestamp: new Date().toISOString(),
    checks: {
      database: 'checking...',
      redis: 'checking...',
      memory: process.memoryUsage(),
      uptime: process.uptime()
    }
  };

  // Check database connection
  try {
    // Your database check logic
    checks.checks.database = 'healthy';
  } catch (error) {
    checks.checks.database = 'unhealthy';
    checks.status = 'error';
  }

  // Check Redis connection
  try {
    // Your Redis check logic
    checks.checks.redis = 'healthy';
  } catch (error) {
    checks.checks.redis = 'unhealthy';
    checks.status = 'error';
  }

  const statusCode = checks.status === 'ok' ? 200 : 503;
  res.status(statusCode).json(checks);
}

Monitoring with Docker Stats

# Monitor container resources
docker stats deepwikiopen-app

# Get detailed container information
docker inspect deepwikiopen-app

# View container logs
docker logs -f deepwikiopen-app

# Execute commands in running container
docker exec -it deepwikiopen-app sh

Prometheus Metrics

# docker/prometheus/prometheus.yml
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'deepwikiopen'
    static_configs:
      - targets: ['app:3000']
    metrics_path: '/api/metrics'

  - job_name: 'postgres'
    static_configs:
      - targets: ['postgres-exporter:9187']

  - job_name: 'redis'
    static_configs:
      - targets: ['redis-exporter:9121']

  - job_name: 'nginx'
    static_configs:
      - targets: ['nginx-exporter:9113']

Scaling Strategies

Docker Compose Scale

# Scale application horizontally
docker-compose up -d --scale app=3

# Scale with load balancer
docker-compose -f docker-compose.yml -f docker-compose.scale.yml up -d
# docker-compose.scale.yml
version: '3.8'

services:
  app:
    deploy:
      replicas: 3
    
  nginx:
    depends_on:
      - app
    volumes:
      - ./docker/nginx/nginx-scale.conf:/etc/nginx/nginx.conf

Load Balancer Configuration

# docker/nginx/nginx-scale.conf
upstream app_servers {
    server app_1:3000;
    server app_2:3000;
    server app_3:3000;
}

server {
    listen 80;
    server_name localhost;

    location / {
        proxy_pass http://app_servers;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Docker Swarm Setup

# Initialize Docker Swarm
docker swarm init

# Deploy stack
docker stack deploy -c docker-compose.swarm.yml deepwikiopen

# Scale services
docker service scale deepwikiopen_app=5
# docker-compose.swarm.yml
version: '3.8'

services:
  app:
    image: ghcr.io/your-org/deepwikiopen:latest
    deploy:
      replicas: 3
      placement:
        constraints:
          - node.role == worker
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
      update_config:
        parallelism: 1
        delay: 10s
        failure_action: rollback
        order: start-first

  postgres:
    image: postgres:15-alpine
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.role == manager
      resources:
        limits:
          memory: 1G
        reservations:
          memory: 512M

networks:
  deepwikiopen-network:
    driver: overlay
    attachable: true

Auto-scaling with Docker Swarm

# Create auto-scaling service
docker service create \
  --name deepwikiopen-app \
  --replicas 2 \
  --limit-cpu 0.5 \
  --limit-memory 512m \
  --reserve-cpu 0.25 \
  --reserve-memory 256m \
  --update-parallelism 1 \
  --update-delay 10s \
  ghcr.io/your-org/deepwikiopen:latest

Security Considerations

Container Security Best Practices

# Use non-root user
FROM node:18-alpine
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nextjs -u 1001

# Set proper file permissions
COPY --chown=nextjs:nodejs . .
USER nextjs

# Use read-only root filesystem
docker run --read-only --tmpfs /tmp deepwikiopen:latest

# Drop capabilities
docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE deepwikiopen:latest

# Set security options
docker run --security-opt=no-new-privileges:true deepwikiopen:latest

Secrets Management

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

services:
  app:
    secrets:
      - db_password
      - jwt_secret
    environment:
      - DATABASE_PASSWORD_FILE=/run/secrets/db_password
      - JWT_SECRET_FILE=/run/secrets/jwt_secret

secrets:
  db_password:
    file: ./secrets/db_password.txt
  jwt_secret:
    file: ./secrets/jwt_secret.txt

Network Security

services:
  app:
    networks:
      - frontend
    # Only expose necessary ports
    expose:
      - "3000"

  postgres:
    networks:
      - backend
    # No external ports
    # Use internal network only

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    internal: true  # No external access

Security Scanning

# Scan images for vulnerabilities
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
  -v /tmp:/tmp anchore/grype:latest \
  ghcr.io/your-org/deepwikiopen:latest

# Use Trivy for comprehensive scanning
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
  aquasec/trivy image ghcr.io/your-org/deepwikiopen:latest

Resource Limits

services:
  app:
    deploy:
      resources:
        limits:
          cpus: '0.50'
          memory: 512M
          pids: 100
        reservations:
          cpus: '0.25'
          memory: 256M
    ulimits:
      nofile:
        soft: 1024
        hard: 2048

Troubleshooting

Common Issues and Solutions

Container Won’t Start

# Check container logs
docker logs deepwikiopen-app

# Check container configuration
docker inspect deepwikiopen-app

# Debug with shell access
docker run -it --entrypoint /bin/sh ghcr.io/your-org/deepwikiopen:latest

Database Connection Issues

# Test database connection
docker exec deepwikiopen-app nc -zv postgres 5432

# Check PostgreSQL logs
docker logs deepwikiopen-postgres

# Test with psql
docker exec -it deepwikiopen-postgres psql -U postgres -d deepwikiopen

Memory Issues

# Monitor memory usage
docker stats deepwikiopen-app

# Check for memory leaks
docker exec deepwikiopen-app cat /proc/meminfo

# Increase memory limits
docker run -m 1g deepwikiopen:latest

Permission Issues

# Check file permissions
docker exec deepwikiopen-app ls -la /app

# Fix ownership
docker exec deepwikiopen-app chown -R nextjs:nodejs /app/data

# Run as different user
docker run --user 1001:1001 deepwikiopen:latest

Debugging Tools

# Enter running container
docker exec -it deepwikiopen-app sh

# Copy files from container
docker cp deepwikiopen-app:/app/logs ./local-logs

# Run health checks manually
docker exec deepwikiopen-app curl -f http://localhost:3000/api/health

# Check network connectivity
docker exec deepwikiopen-app nslookup postgres
docker exec deepwikiopen-app ping redis

Performance Debugging

# Monitor container performance
docker stats --no-stream deepwikiopen-app

# Profile application
docker exec deepwikiopen-app node --prof app.js

# Check disk usage
docker exec deepwikiopen-app df -h
docker system df

Production Deployments

Production-Ready Compose File

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

x-common-variables: &common-variables
  POSTGRES_DB: ${POSTGRES_DB:-deepwikiopen}
  POSTGRES_USER: ${POSTGRES_USER:-postgres}
  POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}

services:
  app:
    image: ghcr.io/your-org/deepwikiopen:${TAG:-latest}
    restart: unless-stopped
    environment:
      <<: *common-variables
      NODE_ENV: production
      DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
    volumes:
      - app-data:/app/data:rw
      - app-logs:/app/logs:rw
    networks:
      - app-network
    depends_on:
      postgres:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/api/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    deploy:
      resources:
        limits:
          memory: 1G
          cpus: '1.0'
        reservations:
          memory: 512M
          cpus: '0.5'

  postgres:
    image: postgres:15-alpine
    restart: unless-stopped
    environment:
      <<: *common-variables
      POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C"
    volumes:
      - postgres-data:/var/lib/postgresql/data:rw
      - postgres-backups:/backups:rw
    networks:
      - app-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
      interval: 10s
      timeout: 5s
      retries: 5
    deploy:
      resources:
        limits:
          memory: 2G
          cpus: '1.0'

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
    volumes:
      - redis-data:/data:rw
    networks:
      - app-network
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 30s
      timeout: 3s
      retries: 3

  nginx:
    image: nginx:alpine
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./nginx/ssl:/etc/nginx/ssl:ro
      - nginx-logs:/var/log/nginx:rw
    depends_on:
      - app
    networks:
      - app-network

volumes:
  app-data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /opt/deepwikiopen/data
  app-logs:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /opt/deepwikiopen/logs
  postgres-data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /opt/deepwikiopen/postgres
  postgres-backups:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /opt/deepwikiopen/backups
  redis-data:
    driver: local
  nginx-logs:
    driver: local

networks:
  app-network:
    driver: bridge

Deployment Scripts

#!/bin/bash
# deploy.sh

set -e

echo "πŸš€ Starting production deployment..."

# Load environment variables
source .env.production

# Pull latest images
echo "πŸ“₯ Pulling latest images..."
docker-compose -f docker-compose.prod.yml pull

# Create backup before deployment
echo "πŸ’Ύ Creating backup..."
./scripts/backup.sh

# Stop services gracefully
echo "πŸ›‘ Stopping services..."
docker-compose -f docker-compose.prod.yml down --remove-orphans

# Start services
echo "▢️ Starting services..."
docker-compose -f docker-compose.prod.yml up -d

# Wait for health checks
echo "⏳ Waiting for services to be healthy..."
timeout 300 docker-compose -f docker-compose.prod.yml exec app \
  bash -c 'while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' localhost:3000/api/health)" != "200" ]]; do sleep 5; done'

# Run database migrations
echo "πŸ”„ Running database migrations..."
docker-compose -f docker-compose.prod.yml exec app npm run migrate

# Clean up old images
echo "🧹 Cleaning up..."
docker image prune -f

echo "βœ… Deployment completed successfully!"

Zero-Downtime Deployment

#!/bin/bash
# zero-downtime-deploy.sh

set -e

# Blue-green deployment script
CURRENT_COLOR=$(docker-compose -f docker-compose.prod.yml ps -q app | head -1)
NEW_COLOR=$([ "$CURRENT_COLOR" == "blue" ] && echo "green" || echo "blue")

echo "πŸ”„ Starting zero-downtime deployment (switching to $NEW_COLOR)..."

# Start new version alongside current
docker-compose -f docker-compose.$NEW_COLOR.yml up -d

# Health check new version
echo "⏳ Waiting for new version to be ready..."
timeout 300 bash -c "until curl -f http://localhost:3001/api/health; do sleep 5; done"

# Switch traffic
echo "πŸ”€ Switching traffic..."
./scripts/switch-traffic.sh $NEW_COLOR

# Stop old version
echo "πŸ›‘ Stopping old version..."
docker-compose -f docker-compose.$CURRENT_COLOR.yml down

echo "βœ… Zero-downtime deployment completed!"

Monitoring and Alerting

# monitoring/docker-compose.monitoring.yml
version: '3.8'

services:
  prometheus:
    image: prom/prometheus:latest
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus-data:/prometheus
    ports:
      - "9090:9090"

  grafana:
    image: grafana/grafana:latest
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
    volumes:
      - grafana-data:/var/lib/grafana
      - ./grafana/provisioning:/etc/grafana/provisioning
    ports:
      - "3001:3000"

  alertmanager:
    image: prom/alertmanager:latest
    volumes:
      - ./alertmanager.yml:/etc/alertmanager/alertmanager.yml
    ports:
      - "9093:9093"

volumes:
  prometheus-data:
  grafana-data:

SSL/TLS Configuration

# nginx/nginx.conf
server {
    listen 443 ssl http2;
    server_name your-domain.com;

    ssl_certificate /etc/nginx/ssl/cert.pem;
    ssl_certificate_key /etc/nginx/ssl/key.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;

    location / {
        proxy_pass http://app:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

server {
    listen 80;
    server_name your-domain.com;
    return 301 https://$server_name$request_uri;
}
This comprehensive Docker deployment guide covers everything from basic setups to production-grade deployments. Use the appropriate sections based on your deployment needs and gradually implement more advanced features as your application grows. Remember to:
  • Always test deployments in a staging environment first
  • Keep your images updated with security patches
  • Monitor resource usage and adjust limits accordingly
  • Implement proper backup and disaster recovery procedures
  • Use secrets management for sensitive data
  • Regular security audits of your containers and configurations