localGPT Docker & Self-Hosted Deployment

GitHub

Chat with your documents on your local device using GPT models. No data leaves your device and 100% private.

22,192 stars Python Python 1 file ยท ~134,648 tokens
RAW Compose
1. Pull Image (DOCKERHUB) docker pull ollama/ollama
2. Docker Run (1-Click Launch) docker run -d --name localgpt -p 11434:11434 --restart always ollama/ollama:latest
3. Podman Run podman run -d --name localgpt -p 11434:11434 --restart always ollama/ollama:latest
4. Skopeo Inspect (Zero-Pull Manifest) skopeo inspect docker://docker.io/ollama/ollama:latest
5. ORAS Pull (OCI Artifact) oras pull ollama/ollama:latest
6. Compose Deployment docker compose up -d
docker-compose.yml
Download .yml
services:
  # Ollama service for LLM inference (optional - can use host Ollama instead)
  ollama:
    image: ollama/ollama:latest
    container_name: rag-ollama
    ports:
      - "11434:11434"
    volumes:
      - ollama_data:/root/.ollama
    environment:
      - OLLAMA_HOST=0.0.0.0
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:11434/api/tags"]
      interval: 30s
      timeout: 10s
      retries: 3
    restart: unless-stopped
    networks:
      - rag-network
    profiles:
      - with-ollama  # Optional service - enable with --profile with-ollama

  # RAG API server
  rag-api:
    build:
      context: .
      dockerfile: Dockerfile.rag-api
    container_name: rag-api
    ports:
      - "8001:8001"
    environment:
      # Use host Ollama by default, or containerized Ollama if enabled
      - OLLAMA_HOST=${OLLAMA_HOST:-http://host.docker.internal:11434}
      - NODE_ENV=production
      - DB_PATH=${DB_PATH:-/app/backend/chat_data.db}
      - LANCEDB_PATH=${LANCEDB_PATH:-/app/lancedb}
      - GENERATION_MODEL=${GENERATION_MODEL:-qwen3.5:9b}
      - ENRICHMENT_MODEL=${ENRICHMENT_MODEL:-qwen3.5:4b}
      - EMBEDDING_MODEL=${EMBEDDING_MODEL:-microsoft/harrier-oss-v1-0.6b}
      - RERANKER_MODEL=${RERANKER_MODEL:-Qwen/Qwen3-Reranker-4B}
    extra_hosts:
      - "host.docker.internal:host-gateway"
    volumes:
      - ./lancedb:/app/lancedb
      - ./index_store:/app/index_store
      - ./shared_uploads:/app/shared_uploads
      # Shared SQLite database - same mount as the backend service
      - ./backend:/app/backend
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8001/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    restart: unless-stopped
    networks:
      - rag-network

  # Backend API server
  backend:
    build:
      context: .
      dockerfile: Dockerfile.backend
    container_name: rag-backend
    ports:
      - "8000:8000"
    environment:
      - NODE_ENV=production
      - RAG_API_URL=${RAG_API_URL:-http://rag-api:8001}
      - OLLAMA_HOST=${OLLAMA_HOST:-http://host.docker.internal:11434}
      - DB_PATH=${DB_PATH:-/app/backend/chat_data.db}
      - LANCEDB_PATH=${LANCEDB_PATH:-/app/lancedb}
      - GENERATION_MODEL=${GENERATION_MODEL:-qwen3.5:9b}
      - ENRICHMENT_MODEL=${ENRICHMENT_MODEL:-qwen3.5:4b}
    extra_hosts:
      - "host.docker.internal:host-gateway"
    volumes:
      # Shared SQLite database - same mount as the rag-api service
      - ./backend:/app/backend
      - ./shared_uploads:/app/shared_uploads
      - ./index_store:/app/index_store
      - ./lancedb:/app/lancedb
    depends_on:
      rag-api:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    restart: unless-stopped
    networks:
      - rag-network

  # Frontend Next.js application
  frontend:
    build:
      context: .
      dockerfile: Dockerfile.frontend
      args:
        NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-http://localhost:8000}
        NEXT_PUBLIC_RAG_API_URL: ${NEXT_PUBLIC_RAG_API_URL:-http://localhost:8001}
    container_name: rag-frontend
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL:-http://localhost:8000}
      - NEXT_PUBLIC_RAG_API_URL=${NEXT_PUBLIC_RAG_API_URL:-http://localhost:8001}
    extra_hosts:
      - "host.docker.internal:host-gateway"
    depends_on:
      backend:
        condition: service_healthy
    healthcheck:
      # node:20-alpine ships busybox wget, not curl
      test: ["CMD-SHELL", "wget -qO- http://localhost:3000 >/dev/null 2>&1 || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 3
    restart: unless-stopped
    networks:
      - rag-network

volumes:
  ollama_data:
    driver: local

networks:
  rag-network:
    driver: bridge