# ============================================================ # AI Markdown Demo — MarkItDown vs Docling vs Unlimited-OCR # ============================================================ # Naming convention: - # # ui :8484 — Comparison UI (Laravel) # api-markitdown :8282 — MarkItDown API (Microsoft) # api-docling :8383 — Docling API (IBM) # api-unlimited-ocr :8181 — Unlimited-OCR API (Baidu) # db-markitdown :5432 — PostgreSQL for markitdown # db-docling :— — PostgreSQL for docling (internal only) # db-unlimited-ocr :— — PostgreSQL for unlimited-ocr (internal only) # db-admin :5050 — Adminer # ============================================================ x-healthcheck-defaults: &healthcheck-defaults interval: 10s timeout: 5s retries: 5 x-service-defaults: &service-defaults restart: unless-stopped networks: - app-network # ========================== # Services # ========================== services: # --- UI layer --------------------------------------------------- ui: image: shinsenter/laravel:php8.3 <<: *service-defaults ports: - "8484:80" volumes: - ./laravel-app:/var/www/html - .:/workspace:ro environment: APP_ENV: production APP_DEBUG: "false" LOG_CHANNEL: stderr depends_on: db-markitdown: condition: service_healthy db-docling: condition: service_healthy db-unlimited-ocr: condition: service_healthy # --- API layer -------------------------------------------------- api-markitdown: build: context: ./services/markitdown-service <<: *service-defaults ports: - "8282:8000" env_file: .env environment: DATABASE_URL: postgresql://${POSTGRES_USER:-admin}:${POSTGRES_PASSWORD:-admin}@db-markitdown:5432/${POSTGRES_DB:-markitdown} VISION_URL: ${VISION_URL:-http://api-vision:8000} extra_hosts: - "host.docker.internal:host-gateway" volumes: - .:/workspace:rw depends_on: db-markitdown: condition: service_healthy api-vision: condition: service_started api-docling: build: context: ./services/docling-service <<: *service-defaults ports: - "8383:8000" env_file: .env environment: DATABASE_URL: postgresql://${POSTGRES_USER:-admin}:${POSTGRES_PASSWORD:-admin}@db-docling:5432/docling VISION_URL: ${VISION_URL:-http://api-vision:8000} extra_hosts: - "host.docker.internal:host-gateway" volumes: - .:/workspace:ro depends_on: db-docling: condition: service_healthy api-vision: condition: service_started api-unlimited-ocr: build: context: ./services/unlimited-ocr-service <<: *service-defaults ports: - "8181:8000" env_file: .env environment: DATABASE_URL: postgresql://${POSTGRES_USER:-admin}:${POSTGRES_PASSWORD:-admin}@db-unlimited-ocr:5432/unlimited_ocr OCR_BASE_URL: ${OCR_BASE_URL:-} OCR_API_KEY: ${OCR_API_KEY:-none} OCR_MODEL: ${OCR_MODEL:-Unlimited-OCR} OCR_DPI: ${OCR_DPI:-300} extra_hosts: - "host.docker.internal:host-gateway" depends_on: db-unlimited-ocr: condition: service_healthy # --- Vision layer (shared OCRFlux, dùng chung cho markitdown + docling) --- api-vision: build: context: ./services/vision-service <<: *service-defaults ports: - "8585:8000" env_file: .env environment: LLM_BASE_URL: ${LLM_BASE_URL:-http://host.docker.internal:11436/v1} LLM_MODEL: ${LLM_MODEL:-ggml-org/Qwen2.5-VL-3B-Instruct-GGUF} extra_hosts: - "host.docker.internal:host-gateway" # --- Database layer --------------------------------------------- db-markitdown: image: postgres:16-alpine <<: *service-defaults env_file: .env environment: POSTGRES_DB: ${POSTGRES_DB:-markitdown} POSTGRES_USER: ${POSTGRES_USER:-admin} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-admin} volumes: - db_markitdown_data:/var/lib/postgresql/data - ./db/init_markitdown.sql:/docker-entrypoint-initdb.d/init_markitdown.sql:ro ports: - "5432:5432" healthcheck: <<: *healthcheck-defaults test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-admin} -d ${POSTGRES_DB:-markitdown}"] db-docling: image: postgres:16-alpine <<: *service-defaults env_file: .env environment: POSTGRES_DB: docling POSTGRES_USER: ${POSTGRES_USER:-admin} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-admin} volumes: - db_docling_data:/var/lib/postgresql/data - ./db/init_docling.sql:/docker-entrypoint-initdb.d/init_markitdown.sql:ro healthcheck: <<: *healthcheck-defaults test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-admin} -d docling"] db-unlimited-ocr: image: postgres:16-alpine <<: *service-defaults env_file: .env environment: POSTGRES_DB: unlimited_ocr POSTGRES_USER: ${POSTGRES_USER:-admin} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-admin} volumes: - db_unlimited_ocr_data:/var/lib/postgresql/data - ./db/init_unlimited_ocr.sql:/docker-entrypoint-initdb.d/init.sql:ro healthcheck: <<: *healthcheck-defaults test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-admin} -d unlimited_ocr"] # --- Admin layer ------------------------------------------------ db-admin: image: adminer:4.8.1 <<: *service-defaults ports: - "5050:8080" environment: ADMINER_DEFAULT_SERVER: db-markitdown depends_on: db-markitdown: condition: service_healthy # ========================== # Infrastructure # ========================== networks: app-network: driver: bridge volumes: db_markitdown_data: db_docling_data: db_unlimited_ocr_data: