# Operations And Configuration ## Runtime Services `docker-compose.yml` defines: - `db` (Postgres 16) - `redis` (Redis 7) - `typesense` (Typesense 29) - `api` (FastAPI backend) - `worker` (RQ worker via `python -m app.worker.run_worker`) - `frontend` (Vite React UI) Persistent volumes: - `db-data` - `redis-data` - `dcm-storage` - `typesense-data` Reset all persisted runtime data: ```bash docker compose down -v ``` ## Core Commands Start or rebuild: ```bash docker compose up --build -d ``` Stop: ```bash docker compose down ``` Tail logs: ```bash docker compose logs -f ``` ## Authentication Model - Legacy shared build-time frontend token behavior was removed. - API now uses server-issued sessions that are stored in HttpOnly cookies (`dcm_session`) with a separate CSRF cookie (`dcm_csrf`). - Bootstrap users are provisioned from environment: - `AUTH_BOOTSTRAP_ADMIN_USERNAME` - `AUTH_BOOTSTRAP_ADMIN_PASSWORD` - optional `AUTH_BOOTSTRAP_USER_USERNAME` - optional `AUTH_BOOTSTRAP_USER_PASSWORD` - Login brute-force protection is enabled by default and keyed by username and source IP: - `AUTH_LOGIN_FAILURE_LIMIT` - `AUTH_LOGIN_FAILURE_WINDOW_SECONDS` - `AUTH_LOGIN_LOCKOUT_BASE_SECONDS` - `AUTH_LOGIN_LOCKOUT_MAX_SECONDS` - Frontend signs in through `/api/v1/auth/login` and relies on browser session persistence for valid cookie-backed sessions. ## DEV And LIVE Configuration Matrix Use `.env.example` as baseline. The table below documents user-managed settings and recommended values. | Variable | Local DEV (HTTP, docker-only) | LIVE (HTTPS behind reverse proxy) | | --- | --- | --- | | `APP_ENV` | `development` | `production` | | `HOST_BIND_IP` | `127.0.0.1` or local LAN bind if needed | `127.0.0.1` (publish behind proxy only) | | `PUBLIC_BASE_URL` | `http://localhost:8000` | `https://api.example.com` | | `VITE_API_BASE` | empty for host-derived `http://:8000/api/v1`, or explicit local URL | `https://api.example.com/api/v1` | | `CORS_ORIGINS` | `["http://localhost:5173","http://localhost:3000"]` | exact frontend origins only, for example `["https://app.example.com"]` | | `REDIS_URL` | `redis://:@redis:6379/0` in isolated local network | `rediss://:@redis.internal:6379/0` | | `REDIS_SECURITY_MODE` | `compat` or `auto` | `strict` | | `REDIS_TLS_MODE` | `allow_insecure` or `auto` | `required` | | `AUTH_LOGIN_FAILURE_LIMIT` | default `5` | tune to identity-protection policy and support requirements | | `AUTH_LOGIN_FAILURE_WINDOW_SECONDS` | default `900` | tune to identity-protection policy and support requirements | | `AUTH_LOGIN_LOCKOUT_BASE_SECONDS` | default `30` | tune to identity-protection policy and support requirements | | `AUTH_LOGIN_LOCKOUT_MAX_SECONDS` | default `900` | tune to identity-protection policy and support requirements | | `PROVIDER_BASE_URL_ALLOW_HTTP` | `true` only when intentionally testing local HTTP provider endpoints | `false` | | `PROVIDER_BASE_URL_ALLOW_PRIVATE_NETWORK` | `true` only for trusted local development targets | `false` | | `PROVIDER_BASE_URL_ALLOWLIST` | allow needed test hosts | explicit production allowlist, for example `["api.openai.com"]` | | `PROCESSING_LOG_STORE_MODEL_IO_TEXT` | `false` by default; temporary `true` only for controlled debugging | `false` | | `PROCESSING_LOG_STORE_PAYLOAD_TEXT` | `false` by default; temporary `true` only for controlled debugging | `false` | | `CONTENT_EXPORT_MAX_DOCUMENTS` | default `250` or lower based on host memory | tuned to production capacity | | `CONTENT_EXPORT_MAX_TOTAL_BYTES` | default `52428800` (50 MiB) or lower | tuned to production capacity | | `CONTENT_EXPORT_RATE_LIMIT_PER_MINUTE` | default `6` | tuned to API throughput and abuse model | `PUBLIC_BASE_URL` must point to the backend API public URL, not the frontend URL. ## HTTPS Proxy Deployment Notes This application supports both: - local HTTP-only operation (no TLS termination in containers) - HTTPS deployment behind a reverse proxy that handles TLS Recommended LIVE pattern: 1. Proxy terminates TLS and forwards to `api` and `frontend` internal HTTP endpoints. 2. Keep container published ports bound to localhost or internal network. 3. Set `PUBLIC_BASE_URL` and `VITE_API_BASE` to final HTTPS URLs. 4. Set `CORS_ORIGINS` to exact HTTPS frontend origins. 5. Credentialed CORS is enabled and constrained for cookie-based sessions with strict origin allowlists. ## Security Controls - CORS uses explicit origin allowlist only; broad origin regex matching is removed. - Worker Redis startup validates URL auth and TLS policy before consuming jobs. - Provider API keys are encrypted at rest with standard AEAD (`cryptography` Fernet). - legacy `enc-v1` payloads are read for backward compatibility - new writes use `enc-v2` - Processing logs default to metadata-only persistence. - Login endpoint applies escalating temporary lockout on repeated failed credentials using Redis-backed subject keys for username and source IP. - Markdown export enforces: - max document count - max total markdown bytes - per-user Redis-backed rate limit - spool-file streaming to avoid unbounded memory archives - User-role document access is owner-scoped for non-admin accounts. ## Frontend Runtime - Frontend no longer consumes `VITE_API_TOKEN`. - Session authentication is cookie-based; browser reloads and new tabs can reuse an active session until it expires or is revoked. - Protected media and file download flows still use authenticated fetch plus blob/object URL handling. ## Validation Checklist After configuration changes: - `GET /api/v1/health` returns healthy response - login succeeds for bootstrap admin user - admin can upload, search, open preview, download, and export markdown - user account can only access its own documents - admin-only settings and processing logs are not accessible by user role - `docker compose logs -f api worker` shows no startup validation failures