# ============================================================================= # Docling Studio — Development stack # # Usage: # docker compose -f docker-compose.dev.yml up # # Includes OpenSearch single-node + Dashboards for search/sync features. # Frontend runs Vite dev server with HMR, backend runs with --reload. # ============================================================================= services: # --- Neo4j (graph-native document structure) --- neo4j: image: neo4j:5.15-community environment: NEO4J_AUTH: ${NEO4J_USER:-neo4j}/${NEO4J_PASSWORD:-changeme} NEO4J_server_memory_heap_initial__size: 512m NEO4J_server_memory_heap_max__size: 1g ports: - "7474:7474" - "7687:7687" volumes: - neo4j_data:/data - neo4j_logs:/logs healthcheck: test: ["CMD-SHELL", "cypher-shell -u $${NEO4J_USER:-neo4j} -p $${NEO4J_PASSWORD:-changeme} 'RETURN 1' || exit 1"] interval: 10s timeout: 5s retries: 10 start_period: 30s # --- OpenSearch (single-node, security disabled for local dev) --- opensearch: image: opensearchproject/opensearch:2 environment: discovery.type: single-node DISABLE_SECURITY_PLUGIN: "true" OPENSEARCH_JAVA_OPTS: "-Xms512m -Xmx512m" ports: - "9200:9200" volumes: - opensearch_data:/usr/share/opensearch/data healthcheck: test: ["CMD-SHELL", "curl -sf http://localhost:9200/_cluster/health || exit 1"] interval: 10s timeout: 5s retries: 10 # --- OpenSearch Dashboards (index inspection UI) --- opensearch-dashboards: image: opensearchproject/opensearch-dashboards:2 environment: OPENSEARCH_HOSTS: '["http://opensearch:9200"]' DISABLE_SECURITY_DASHBOARDS_PLUGIN: "true" ports: - "5601:5601" depends_on: opensearch: condition: service_healthy # --- Embedding service (sentence-transformers) --- embedding: build: context: ./embedding-service ports: - "8001:8001" environment: EMBEDDING_MODEL: ${EMBEDDING_MODEL:-all-MiniLM-L6-v2} EMBEDDING_BATCH_SIZE: ${EMBEDDING_BATCH_SIZE:-64} healthcheck: test: ["CMD-SHELL", "curl -sf http://localhost:8001/health || exit 1"] interval: 10s timeout: 5s retries: 10 deploy: resources: limits: memory: 2g # --- Backend (FastAPI with hot-reload) --- document-parser: build: context: ./document-parser target: ${CONVERSION_MODE:-local} ports: - "8000:8000" volumes: - ./document-parser:/app - uploads_data:/app/uploads - db_data:/app/data environment: CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost:3000,http://localhost:5173} DOCLING_SERVE_URL: ${DOCLING_SERVE_URL:-} DOCLING_SERVE_API_KEY: ${DOCLING_SERVE_API_KEY:-} RATE_LIMIT_RPM: ${RATE_LIMIT_RPM:-100} MAX_FILE_SIZE_MB: ${MAX_FILE_SIZE_MB:-50} BATCH_PAGE_SIZE: ${BATCH_PAGE_SIZE:-10} OPENSEARCH_URL: http://opensearch:9200 EMBEDDING_URL: http://embedding:8001 NEO4J_URI: bolt://neo4j:7687 NEO4J_USER: ${NEO4J_USER:-neo4j} NEO4J_PASSWORD: ${NEO4J_PASSWORD:-changeme} command: ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"] depends_on: opensearch: condition: service_healthy embedding: condition: service_healthy neo4j: condition: service_healthy deploy: resources: limits: memory: 4g # --- Frontend (Vite dev server with HMR) --- frontend: image: node:20-alpine working_dir: /app ports: - "3000:3000" volumes: - ./frontend:/app - frontend_node_modules:/app/node_modules environment: VITE_APP_VERSION: dev command: ["sh", "-c", "npm install && npm run dev -- --host"] depends_on: - document-parser volumes: opensearch_data: neo4j_data: neo4j_logs: uploads_data: db_data: frontend_node_modules: