b255a0f90e
Renames src/fabledassistant -> src/scribe and all imports, plus the default DB name and DB user/password (fabled -> scribe) in config + compose. 952 refs / 154 files. Reverses the old 'internal name stays fabledassistant' convention. Code-only: live databases are still physically named 'fabledassistant'. Deployed environments must set POSTGRES_DB / POSTGRES_USER (or rename the DB) since the defaults now resolve to 'scribe'. Repo (FabledScribe), git host (fabledsword), MCP (fabled-git) and the image name (fabledscribe) are intentionally unchanged. ruff check src/ clean locally; CI (typecheck + pytest) is the gate. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
156 lines
6.3 KiB
Markdown
156 lines
6.3 KiB
Markdown
# 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
|