Files
bvandeusen 8c1b19f49c chore(docs): retire dead fable-mcp wheel-distribution refs; untrack docs/superpowers
The old standalone fable-mcp wheel/download flow is gone from code (no route,
no Dockerfile build, no FABLE_MCP_DIST_DIR). Update api-keys-and-mcp,
api-reference, architecture, configuration, development to describe the
in-app HTTP MCP at /mcp (Bearer auth). Untrack the 18 committed
docs/superpowers/ files so the existing .gitignore takes effect.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 22:42:58 -04:00

6.1 KiB
Raw Permalink Blame History

Configuration

Configuration is via environment variables. The docker-compose.yml file sets defaults for local development; override them in a .env file (gitignored).

Environment Variables

Core

Variable Default Description
DATABASE_URL postgresql+asyncpg://fabled:fabled@db/scribe PostgreSQL async connection string
SECRET_KEY dev-secret-change-me Session signing key — change this in production
SECRET_KEY_FILE Path to a Docker secret file containing the key (alternative to SECRET_KEY)
LOG_LEVEL INFO Logging verbosity (DEBUG, INFO, WARNING, ERROR)
SECURE_COOKIES false Set true when running behind TLS
BASE_URL Public URL (e.g. https://notes.example.com) — required for OIDC redirect URIs and email links

LLM / Ollama

Variable Default Description
OLLAMA_URL http://ollama:11434 Ollama API base URL
OLLAMA_MODEL llama3.2 Default LLM model (used as fallback; per-user setting overrides this)
EMBEDDING_MODEL nomic-embed-text Model used for semantic search / RAG embeddings
OLLAMA_NUM_CTX 16384 Context window size passed to Ollama for all generation calls

Authentication / OIDC

Variable Default Description
LOCAL_AUTH_ENABLED true Set false to disable local username/password login (SSO-only mode)
OIDC_ISSUER OIDC issuer URL (e.g. https://auth.example.com/application/o/fabled/)
OIDC_CLIENT_ID OIDC client ID
OIDC_CLIENT_SECRET OIDC client secret
OIDC_CLIENT_SECRET_FILE Docker secret file alternative to OIDC_CLIENT_SECRET
OIDC_SCOPES openid profile email Space-separated OIDC scopes to request

See sso-oauth.md for provider-specific setup.

Security / Proxy

Variable Default Description
TRUST_PROXY_HEADERS false Set true when behind a trusted reverse proxy to read real IP from X-Forwarded-For / X-Real-IP

Web Search / Images

Variable Default Description
SEARXNG_URL SearXNG base URL for web search and image search tools
IMAGE_CACHE_DIR /data/images Directory for cached search images
IMAGE_MAX_BYTES 5242880 (5 MB) Maximum size for cached images

Data / Logging

Variable Default Description
LOG_RETENTION_DAYS 90 Days to keep app logs before automatic pruning
DATA_DIR /data Root directory for persistent data (VAPID keys, backups)

Docker Compose Setup

Development (docker-compose.yml)

# Copy the example env file
cp .env.example .env
# Edit .env to set a real SECRET_KEY

# Start the stack
docker compose up --build

# App available at http://localhost:5000

The first user to register becomes admin. Registration auto-closes after that (re-enable from Settings → Users).

Production (docker-compose.prod.yml)

The production compose file adds:

  • Docker Secrets for SECRET_KEY_FILE and DATABASE_URL_FILE
  • Network isolation (internal bridge for DB + Ollama; only the app is externally accessible)
  • Health checks and resource limits
# Create Docker secrets
echo "$(python3 -c 'import secrets; print(secrets.token_hex(32))')" | docker secret create fabled_secret_key -
echo "postgresql+asyncpg://fabled:strongpassword@db/scribe" | docker secret create fabled_db_url -

# Deploy
docker stack deploy -c docker-compose.prod.yml fabled

Production Deployment

Reverse Proxy (Required)

Fabled Assistant does not handle SSL/TLS. Run it behind a reverse proxy:

  • Nginx, Traefik, or Caddy in front of the app container
  • Terminate TLS at the proxy; forward to port 5000
  • Do not expose port 5000 directly to the internet
  • Rate-limit auth endpoints: ≤ 5 req/min per IP on /api/auth/login and /api/auth/register

Example Nginx location block:

location / {
    proxy_pass http://127.0.0.1:5000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    # Required for SSE streaming
    proxy_buffering off;
    proxy_read_timeout 600s;
    proxy_send_timeout 600s;
}

If using TRUST_PROXY_HEADERS=true, ensure your proxy strips any client-supplied X-Forwarded-For headers before adding its own.

Security Checklist

  • Strong SECRET_KEY — generate with:
    python3 -c "import secrets; print(secrets.token_hex(32))"
    
    Or use Docker Secrets via SECRET_KEY_FILE.
  • SECURE_COOKIES=true — must be set when running behind TLS.
  • BASE_URL — set to your public URL; required for OIDC redirects and email links.
  • Registration — auto-closes after the first user (admin). Re-enable from Settings → Users or send invite links.
  • Session invalidation — changing or resetting a password bumps session_version, evicting all other active sessions. Button also available in Settings → Account.
  • Keep Ollama on an internal network — both compose files keep Ollama off the host network. Never expose the Ollama port publicly.
  • Default SECRET_KEY warning — the app logs a WARNING on startup if the default dev key is in use.

Model Management

Models are managed through Settings → General → Model Management in the web UI. You can:

  • Pull new models by name (streams progress via SSE)
  • View installed models with size and loaded/unloaded state
  • Delete unused models

The app auto-warms user-preferred models on startup (only models already installed — never auto-pulls). The embedding model (nomic-embed-text) is auto-pulled on startup if missing.

Recommended models for 2× 8 GB GPU:

  • qwen3:8b — strong reasoning + tools, fits in 8 GB, supports thinking mode
  • qwen2.5:7b — fast, tool-capable, smaller context
  • llama3.1:8b — reliable baseline, widely tested with tools