feat(library): deploy Library infrastructure (Neo4j, Wiki.js, Library Desk API)

Implements The Library system - a knowledge management and HybridRAG platform.

**Stack Files:**
- neo4j.yml: Knowledge graph database with APOC plugin
- wiki.yml: Wiki.js for human-facing dossier management
- library-desk.yml: FastAPI coordination service

**Library Desk Service:**
- FastAPI application following best practices
- Pydantic Settings for configuration management
- Bearer token authentication
- Health monitoring endpoints
- Stub endpoints for future HybridRAG implementation

**Features:**
- All services on docker-dataplane network
- Proper healthchecks for all containers
- Neo4j password validation (alphanumeric only)
- Wiki.js healthcheck fixed for IPv4/IPv6 compatibility
- Python 3.12+ with CVE-checked dependencies
- Minor version locking for stability

**Endpoints:**
- Neo4j Browser: http://192.168.86.149:7474
- Wiki.js: http://192.168.86.149:8088
- Library Desk API: http://192.168.86.149:8089
- API Docs: http://192.168.86.149:8089/docs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-08 17:35:09 +01:00
co-authored by Claude Opus 4.5
parent 14574e837b
commit e886a2f9ba
8 changed files with 857 additions and 0 deletions
+151
View File
@@ -0,0 +1,151 @@
version: '3.8'
# Library - Front Desk API (Coordination Service)
# Application Layer
# Port: 8089 (HTTP)
# GPU: No
# Storage: SSD (venv, logs)
services:
library-desk:
image: python:3.12-slim
container_name: library-desk
restart: unless-stopped
ports:
- "8089:8089" # FastAPI HTTP
volumes:
# Mount source code for live editing
- /home/jpmschweitzer/Projects/portainer-core/services/library-desk:/app
# Persist container's venv for fast restarts
- /home/jpmschweitzer/docker-data/library-desk/venv:/venv
working_dir: /app
command: >
sh -c "
echo 'Installing system dependencies...' &&
apt-get update -qq &&
apt-get install -y --no-install-recommends curl >/dev/null 2>&1 &&
rm -rf /var/lib/apt/lists/* &&
echo 'Setting up Python environment...' &&
if [ ! -f /venv/bin/python ]; then
echo 'Initializing venv...' &&
python3 -m venv --clear /venv;
fi &&
echo 'Upgrading pip...' &&
/venv/bin/python -m pip install --upgrade pip --quiet &&
echo 'Installing dependencies from requirements.txt...' &&
/venv/bin/python -m pip install -r /app/requirements.txt --quiet &&
echo 'Starting Library Desk API...' &&
/venv/bin/python -m uvicorn src.main:app --host 0.0.0.0 --port 8089 --workers 2
"
environment:
# API Configuration
- LIBRARY_API_KEY=${LIBRARY_API_KEY}
# Neo4j Configuration
- NEO4J_URI=bolt://neo4j:7687
- NEO4J_USER=neo4j
- NEO4J_PASSWORD=${NEO4J_PASSWORD}
# Qdrant Configuration
- QDRANT_HOST=qdrant
- QDRANT_PORT=6333
# Wiki.js Configuration
- WIKIJS_URL=http://wiki:3000
- WIKIJS_API_KEY=${WIKIJS_API_KEY}
# SearXNG Configuration
- SEARXNG_URL=http://searxng:8080
# Ollama Configuration (for embeddings)
- OLLAMA_URL=http://ollama:11434
- OLLAMA_MODEL=nomic-embed-text
# Redis Configuration
- REDIS_HOST=redis-shared
- REDIS_PORT=6379
- REDIS_DB=2
# Python Configuration
- PYTHONUNBUFFERED=1
- TZ=${TZ:-Europe/Amsterdam}
networks:
- docker-dataplane
deploy:
resources:
reservations:
memory: 256M
limits:
memory: 768M
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8089/health')"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
networks:
docker-dataplane:
external: true
name: docker-dataplane
# ⚠️ SECURITY WARNING:
# Set these in environment variables before deploying:
# - LIBRARY_API_KEY (generate with: openssl rand -hex 32)
# - NEO4J_PASSWORD (from library-neo4j deployment)
# - LIBRARY_DB_PASSWORD (from library-wiki deployment)
# - WIKIJS_API_KEY (from Wiki.js admin panel → API Access)
#
# Prerequisites:
# 1. Create /home/jpmschweitzer/Projects/portainer-core/services/library/services/front-desk/
# 2. Create requirements.txt (see DEPLOYMENT.md Phase 4.3)
# 3. Create main.py with FastAPI app (see DEPLOYMENT.md Phase 4.3)
#
# API Endpoints (once implemented):
# Query:
# POST /query/hybrid # HybridRAG (graph + vector + web)
# POST /query/semantic # Vector search only
# POST /query/graph # Graph traversal only
# GET /query/related/{id} # Find related content
#
# Content Management:
# POST /ingest/document # Index new document
# POST /ingest/wiki-page # Sync Wiki.js page
# POST /wiki/dossier # Create dossier (proxies to Wiki.js)
# PUT /wiki/dossier/{id} # Update dossier
# DELETE /wiki/dossier/{id} # Delete dossier
#
# Graph Operations:
# GET /graph/entities # List entities
# GET /graph/mindmap/{id} # Generate mind map for dossier
# POST /graph/query # Execute Cypher query
#
# Deduplication:
# POST /deduplicate/find # Find potential duplicates
# POST /deduplicate/merge # Merge duplicate entities
#
# System:
# GET /stats # System statistics
# GET /health # Health check
#
# API Documentation:
# - Interactive docs: http://192.168.86.149:8089/docs
# - OpenAPI spec: http://192.168.86.149:8089/openapi.json
#
# Features:
# - HybridRAG queries (Neo4j + Qdrant + SearXNG)
# - Document ingestion and indexing
# - Entity extraction and relationship mapping
# - Mind map generation
# - Deduplication detection
# - Wiki.js API proxy
#
# Dependencies:
# - Neo4j (knowledge graph)
# - Qdrant (vector search)
# - Wiki.js (wiki operations)
# - SearXNG (web search)
# - Ollama (embeddings)
# - Redis (caching)
+77
View File
@@ -0,0 +1,77 @@
version: '3.8'
# Library - Neo4j Knowledge Graph
# Storage Layer
# Ports: 7474 (Browser), 7687 (Bolt)
# GPU: No
# Storage: SSD (graph database)
services:
neo4j:
image: neo4j:5-community
container_name: neo4j
restart: unless-stopped
ports:
- "7474:7474" # Neo4j Browser (web UI)
- "7687:7687" # Bolt protocol (API)
volumes:
# Graph database on SSD for performance
- /home/jpmschweitzer/docker-data/library-neo4j/data:/data
- /home/jpmschweitzer/docker-data/library-neo4j/logs:/logs
- /home/jpmschweitzer/docker-data/library-neo4j/plugins:/plugins
environment:
- NEO4J_AUTH=neo4j/${NEO4J_PASSWORD}
- NEO4J_PLUGINS=["apoc"]
- NEO4J_dbms_memory_heap_initial__size=512m
- NEO4J_dbms_memory_heap_max__size=2g
- NEO4J_dbms_memory_pagecache_size=512m
- NEO4J_apoc_export_file_enabled=true
- NEO4J_apoc_import_file_enabled=true
- NEO4J_apoc_import_file_use__neo4j__config=true
- TZ=${TZ:-Europe/Amsterdam}
networks:
- docker-dataplane
deploy:
resources:
reservations:
memory: 1G
limits:
memory: 4G
healthcheck:
test: ["CMD", "cypher-shell", "-u", "neo4j", "-p", "${NEO4J_PASSWORD}", "RETURN 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
networks:
docker-dataplane:
external: true
name: docker-dataplane
# ⚠️ SECURITY WARNING:
# Set NEO4J_PASSWORD in environment variables before deploying!
# Use a strong, unique password.
#
# After Deployment:
# 1. Access Neo4j Browser: http://192.168.86.149:7474
# 2. Login: neo4j / <NEO4J_PASSWORD>
# 3. Run schema initialization (see DEPLOYMENT.md Phase 4.1)
# 4. Install APOC plugin (should auto-install from NEO4J_PLUGINS setting)
#
# Features:
# - Knowledge graph for entities, relationships, versions
# - APOC procedures for advanced graph operations
# - Cypher query language for graph traversal
# - Mind map generation for Wiki.js
# - Version tracking for documentation
# - Compatibility relationships between projects
#
# Memory Configuration:
# - Heap: 512MB initial → 2GB max
# - Page cache: 512MB
# - Reserved: 1GB, Limit: 4GB
#
# Backups:
# - Managed by Scheduler (weekly, Sunday 03:00)
# - Location: /mnt/media/backups/library/neo4j/
+97
View File
@@ -0,0 +1,97 @@
version: '3.8'
# Library - Wiki.js (Knowledge Wiki)
# Application Layer
# Port: 8088 (HTTP)
# GPU: No
# Storage: PostgreSQL (shared), SSD (uploads)
services:
wiki:
image: ghcr.io/requarks/wiki:2
container_name: wiki
restart: unless-stopped
ports:
- "8088:3000" # HTTP web interface
volumes:
# Uploads and backups on HDD
- /mnt/media/library/wiki:/wiki/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
environment:
# Database configuration (PostgreSQL shared)
- DB_TYPE=postgres
- DB_HOST=postgres-shared
- DB_PORT=5432
- DB_NAME=library
- DB_USER=library_user
- DB_PASS=${LIBRARY_DB_PASSWORD}
# Redis cache configuration (DB 2)
- REDIS_HOST=redis-shared
- REDIS_PORT=6379
- REDIS_DB=2
# Application configuration
- WIKI_ADMIN_EMAIL=admin@schweitz.net
- HA_ACTIVE=false
- TZ=${TZ:-Europe/Amsterdam}
networks:
- docker-dataplane
deploy:
resources:
reservations:
memory: 256M
limits:
memory: 1G
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:3000/healthz"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
networks:
docker-dataplane:
external: true
name: docker-dataplane
# ⚠️ SECURITY WARNING:
# Set LIBRARY_DB_PASSWORD in environment variables before deploying!
# This should match the password created in PostgreSQL (see DEPLOYMENT.md Phase 1.1)
#
# After Deployment:
# 1. Access http://192.168.86.149:8088
# 2. Complete initial setup wizard:
# - Admin account (use strong password!)
# - Site URL: http://192.168.86.149:8088 or https://library.schweitz.net
# - Telemetry: Optional
# 3. Enable API Access:
# - Administration → API Access
# - Generate New Key → Save to .env.library as WIKIJS_API_KEY
# 4. Configure storage:
# - Administration → Storage
# - Enable Git storage (optional, for version control)
#
# Features:
# - Markdown editing with live preview
# - Cross-dossier linking (wikilinks)
# - Full-text search
# - Version history
# - User authentication and authorization
# - API for Front Desk integration
# - Mind map embedding (via Front Desk)
#
# Integration:
# - Front Desk proxies CRUD operations via Wiki.js API
# - Content changes trigger re-indexing in Qdrant
# - Entity extraction updates Neo4j graph
#
# Backups:
# - Database: Managed by Scheduler (daily, 02:00)
# - Content export: Managed by Scheduler (daily, 02:00)
# - Location: /mnt/media/backups/library/wikijs/
#
# External Access (Optional):
# - Nginx Proxy Manager: library.schweitz.net → library-wiki:3000
# - SSL: Let's Encrypt via NPM