# 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](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) | ### Fable MCP Distribution | Variable | Default | Description | |----------|---------|-------------| | `FABLE_MCP_DIST_DIR` | `/app/dist` | Directory where the bundled `fable-mcp` wheel is placed at build time | ## Docker Compose Setup ### Development (`docker-compose.yml`) ```bash # 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 ```bash # 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: ```nginx 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: ```bash 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