services: app: build: . ports: - "5000:5000" depends_on: db: condition: service_healthy ollama: condition: service_started volumes: - app_data:/data # To use a bind mount instead (gives direct host access to all app data): # - ./data:/data environment: DATABASE_URL: "postgresql+asyncpg://${POSTGRES_USER:-fabled}:${POSTGRES_PASSWORD:-fabled}@db:5432/${POSTGRES_DB:-fabledassistant}" OLLAMA_URL: "http://ollama:11434" OLLAMA_MODEL: "${OLLAMA_MODEL:-qwen3:14b}" SECRET_KEY: "${SECRET_KEY:-dev-secret-change-me}" # Uncomment and set to enable web research and image search via SearXNG: # SEARXNG_URL: "http://searxng:8080" # IMAGE_CACHE_DIR: /data/images # default, change if using a different mount path # IMAGE_MAX_BYTES: "5242880" # 5 MB per image, adjust if needed # Push notifications (VAPID keys - generate with: python -c "from py_vapid import Vapid01; v=Vapid01(); v.generate_keys(); print(v.private_key, v.public_key)") VAPID_PRIVATE_KEY: "${VAPID_PRIVATE_KEY:-}" VAPID_PUBLIC_KEY: "${VAPID_PUBLIC_KEY:-}" VAPID_CLAIMS_SUB: "${VAPID_CLAIMS_SUB:-mailto:admin@fabledassistant.local}" healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:5000/api/health')"] interval: 10s timeout: 5s retries: 5 start_period: 30s db: image: postgres:16-alpine volumes: - pgdata:/var/lib/postgresql/data environment: POSTGRES_USER: ${POSTGRES_USER:-fabled} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-fabled} POSTGRES_DB: ${POSTGRES_DB:-fabledassistant} healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-fabled}"] interval: 5s timeout: 5s retries: 5 ollama: image: ollama/ollama volumes: - ollama_models:/root/.ollama environment: OLLAMA_MAX_LOADED_MODELS: "2" OLLAMA_NUM_PARALLEL: "2" OLLAMA_KEEP_ALIVE: "30m" OLLAMA_FLASH_ATTENTION: "1" deploy: resources: reservations: devices: - driver: nvidia count: all capabilities: [gpu] volumes: pgdata: ollama_models: app_data: