services: # ────────────────────────────────────────────── # Neo4j Graph Database # ────────────────────────────────────────────── neo4j: image: neo4j:5.12.0 container_name: graphrag_neo4j restart: unless-stopped ports: # Only expose to localhost — not 0.0.0.0 - "127.0.0.1:7474:7474" # Neo4j Browser Console (HTTP) - "127.0.0.1:7687:7687" # Bolt protocol (Django driver) environment: - NEO4J_AUTH=neo4j/password # Allow APOC and GDS plugins - NEO4J_PLUGINS=["apoc", "graph-data-science"] # Grant full permissions to GDS and APOC procedures - NEO4J_dbms_security_procedures_unrestricted=apoc.*,gds.* - NEO4J_dbms_security_procedures_allowlist=apoc.*,gds.* volumes: - neo4j_data:/data - neo4j_logs:/logs - neo4j_import:/import - neo4j_plugins:/plugins networks: - graphrag-network healthcheck: test: ["CMD-SHELL", "cypher-shell -u neo4j -p password 'RETURN 1' || exit 1"] interval: 10s timeout: 10s retries: 5 start_period: 20s # ────────────────────────────────────────────── # Django Backend API (GraphRAG) # ────────────────────────────────────────────── backend: build: context: ./backend dockerfile: Dockerfile container_name: graphrag_backend command: > sh -c "python manage.py migrate --noinput && gunicorn config.wsgi:application --bind 0.0.0.0:8000 --workers 4 --threads 2 --timeout 300 --access-logfile - --error-logfile -" restart: unless-stopped ports: # Only expose to localhost — not 0.0.0.0 - "127.0.0.1:8000:8000" env_file: - .env environment: # Override .env values for Docker network - NEO4J_URI=bolt://neo4j:7687 - DEBUG=False - ALLOWED_HOSTS=localhost,127.0.0.1,backend volumes: # Persist SQLite database (user accounts, document metadata) - sqlite_data:/app/db # Persist ChromaDB vector store - chroma_data:/app/chroma_db # Persist uploaded documents - upload_data:/app/uploaded_documents depends_on: neo4j: condition: service_healthy networks: - graphrag-network healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/api/health/"] interval: 30s timeout: 5s start_period: 15s retries: 3 # ────────────────────────────────────────────── # Next.js Frontend # ────────────────────────────────────────────── frontend: build: context: ./frontend dockerfile: Dockerfile args: NEXT_PUBLIC_API_URL: http://localhost:8000/api container_name: graphrag_frontend restart: unless-stopped ports: - "127.0.0.1:3000:3000" environment: - NEXT_PUBLIC_API_URL=http://localhost:8000/api depends_on: backend: condition: service_healthy networks: - graphrag-network # ────────────────────────────────────────────── # Named volumes # ────────────────────────────────────────────── volumes: neo4j_data: neo4j_logs: neo4j_import: neo4j_plugins: sqlite_data: chroma_data: upload_data: # ────────────────────────────────────────────── # Internal network (services only) # ────────────────────────────────────────────── networks: graphrag-network: driver: bridge