mirror of
https://github.com/odysseus-dev/odysseus.git
synced 2026-08-29 18:31:47 +00:00
* fix(auth): derive the session cookie Secure flag from the request scheme SECURE_COOKIES only marked the login cookie Secure when it was explicitly set to true, so an HTTPS login on an install that never set it handed out a session cookie the browser is happy to send back in cleartext. Unset now derives the flag from the request: the connection scheme, which uvicorn's proxy-headers middleware rewrites for the proxies it trusts, or X-Forwarded-Proto for a terminator that is not on a trusted address. That is the same test core/middleware.py already applies before sending HSTS, so the two stop disagreeing about whether a request arrived over TLS. An explicit true still forces the flag on and an explicit false turns it off for an install still answering on both HTTP and HTTPS. Strictly more Secure flags than before and never fewer. Empty counts as unset, because docker-compose pinned SECURE_COOKIES=false for every container; the compose files now pass the variable through unset, the way FASTEMBED_CACHE_PATH already does. The helper and its decision order come from #3799, which was closed for being too large to review and whose six replacement PRs dropped this fix. Part of #3803. * docs(setup): flag the leftover SECURE_COOKIES=false on upgrades The old default was false, so an install set up before scheme derivation can still carry an explicit SECURE_COOKIES=false in its own .env. That value stays authoritative, so HTTPS logins keep getting a non-Secure session cookie even after the tracked compose defaults are updated by a pull. Say so where people look: the security notes and the variable's own comment in .env.example. * docs(setup): align TLS guidance with scheme-derived cookies --------- Co-authored-by: Alexandre Teixeira <alexandremagteixeira@gmail.com>
268 lines
12 KiB
Text
268 lines
12 KiB
Text
# Odysseus UI — Environment Configuration
|
|
# Copy this file to .env and fill in your values.
|
|
|
|
# ============================================================
|
|
# LLM Configuration
|
|
# ============================================================
|
|
|
|
# Primary LLM host (default: localhost)
|
|
LLM_HOST=localhost
|
|
|
|
# Additional LLM hosts, comma-separated (for model discovery)
|
|
# Use hostnames/IPs only; Odysseus scans common serve ports, including Ollama's 11434.
|
|
# LLM_HOSTS=llm-host.local,backup-llm.local
|
|
|
|
# Optional Ollama base URL. In Docker, host Ollama is usually reachable here
|
|
# when started with OLLAMA_HOST=0.0.0.0:11434.
|
|
# OLLAMA_BASE_URL=http://host.docker.internal:11434/v1
|
|
|
|
# Optional LM Studio URL. In Docker, host LM Studio is reachable here
|
|
# when LM Studio is set to serve on all interfaces (0.0.0.0).
|
|
# LM_STUDIO_URL=http://host.docker.internal:1234
|
|
|
|
# OpenAI API key (only needed if using OpenAI models).
|
|
# Do not commit real keys. Keep this commented until needed.
|
|
# OPENAI_API_KEY=your_openai_api_key_here
|
|
|
|
# Research service LLM endpoint
|
|
# RESEARCH_LLM_ENDPOINT=http://localhost:8000/v1/chat/completions
|
|
|
|
# Extra CA bundle for LLM providers whose TLS chain isn't in the default
|
|
# trust store. Layered ON TOP of the system / certifi bundle — verification
|
|
# stays on for every host, the trust set just gets larger. Useful for:
|
|
# - GigaChat / Sber (Russian Trusted Root CA): without this the endpoint
|
|
# shows offline with CERTIFICATE_VERIFY_FAILED — self-signed certificate
|
|
# in certificate chain.
|
|
# - On-premise / corporate LLM gateways with an internal CA.
|
|
# Point at a PEM file containing the missing root(s).
|
|
# LLM_CA_BUNDLE=/etc/odysseus/ca/extra-roots.pem
|
|
|
|
# ============================================================
|
|
# Search & Web
|
|
# ============================================================
|
|
|
|
# SearXNG instance URL (self-hosted, for web search).
|
|
# Docker Compose overrides this to http://searxng:8080 for in-network access.
|
|
SEARXNG_INSTANCE=http://localhost:8080
|
|
|
|
# Optional SearXNG cookie/CSRF secret. If blank, Docker generates one on first boot
|
|
# and stores it in the searxng-data volume.
|
|
# SEARXNG_SECRET=
|
|
|
|
# ============================================================
|
|
# Database
|
|
# ============================================================
|
|
|
|
# SQLite database path (default: sqlite:///./data/app.db)
|
|
# DATABASE_URL=sqlite:///./data/app.db
|
|
|
|
# ============================================================
|
|
# Data directory
|
|
# ============================================================
|
|
# Move everything that lives under data/ - settings, sessions, database, auth,
|
|
# cache, uploads, etc. - to another path:
|
|
# ODYSSEUS_DATA_DIR=C:\path\to\dir
|
|
|
|
# ============================================================
|
|
# Auth & Security
|
|
# ============================================================
|
|
|
|
# Enable authentication (default: true)
|
|
# AUTH_ENABLED=true
|
|
|
|
# Host bind address and port for the Odysseus web UI in Docker Compose.
|
|
# Keep APP_BIND on loopback unless you intentionally want LAN/reverse-proxy access.
|
|
# APP_BIND=127.0.0.1
|
|
# Change this if another local service already uses 7000 (macOS AirPlay often does).
|
|
# APP_PORT=7000
|
|
|
|
# Optional HTTP address advertised in companion/mobile pairing codes. Set this
|
|
# when Docker would otherwise advertise a container address or loopback. Use a
|
|
# LAN or Tailscale IPv4 address, a single-label hostname, or an mDNS *.local
|
|
# name that the phone can reach. HTTPS and public hostnames are not supported
|
|
# by the current companion client. Do not include credentials, a path, query,
|
|
# or fragment.
|
|
# COMPANION_BASE_URL=http://192.168.1.50:7000
|
|
|
|
# Development-only auth bypass for loopback requests.
|
|
# Keep false for Docker, LAN, reverse proxy, and any shared deployment.
|
|
# LOCALHOST_BYPASS=false
|
|
|
|
# Mark session cookies Secure. Left unset, this follows the request scheme:
|
|
# an HTTPS login gets a Secure cookie, a plain-HTTP one does not. Set true to
|
|
# force it on, or false to force it off while you still serve plain HTTP.
|
|
# Upgrading: this used to default to false. Drop a leftover SECURE_COOKIES=false
|
|
# from your .env unless you still need that escape hatch — it keeps HTTPS logins
|
|
# on a non-Secure cookie.
|
|
# SECURE_COOKIES=true
|
|
|
|
# Optional: pre-seed the first admin password during setup.
|
|
# Do not commit a real password.
|
|
# ODYSSEUS_ADMIN_PASSWORD=change_me_before_first_boot
|
|
|
|
# CORS allowed origins (default: localhost-only; restrict to your public origin in production)
|
|
# ALLOWED_ORIGINS=http://localhost:7000,http://localhost:8000
|
|
|
|
# ============================================================
|
|
# ChromaDB (vector store)
|
|
# ============================================================
|
|
|
|
# ChromaDB service host.
|
|
# Manual host run: localhost:8100 when using `docker run -p 8100:8000 chromadb/chroma`.
|
|
# Docker Compose overrides these to chromadb:8000 for in-network access.
|
|
# CHROMADB_HOST=localhost
|
|
# CHROMADB_PORT=8100
|
|
|
|
# Docker Compose host-port bind addresses for bundled services.
|
|
# Defaults are loopback-only for safety. To expose ntfy only on Tailscale,
|
|
# set NTFY_BIND to your host's Tailscale IP and update NTFY_BASE_URL.
|
|
# CHROMADB_BIND=127.0.0.1
|
|
# NTFY_BIND=127.0.0.1
|
|
# NTFY_BASE_URL=http://localhost:8091
|
|
# Example:
|
|
# NTFY_BIND=100.x.y.z
|
|
# NTFY_BASE_URL=http://100.x.y.z:8091
|
|
|
|
# ============================================================
|
|
# RAG / Embeddings
|
|
# ============================================================
|
|
|
|
# Embedding API endpoint (OpenAI-compatible /v1/embeddings)
|
|
# Default: http://{LLM_HOST}:11434/v1/embeddings (ollama)
|
|
# EMBEDDING_URL=http://localhost:11434/v1/embeddings
|
|
|
|
# Embedding API key (if there's one)
|
|
# EMBEDDING_API_KEY=embedding_api_key_here
|
|
|
|
# Embedding model name (must be available at the endpoint above)
|
|
# EMBEDDING_MODEL=all-minilm:l6-v2
|
|
|
|
# Local fallback embedding model (used when no HTTP embedding API is available)
|
|
# Uses fastembed (ONNX) — downloads model on first run (~50MB)
|
|
# FASTEMBED_MODEL=sentence-transformers/all-MiniLM-L6-v2
|
|
# FASTEMBED_CACHE_PATH= # defaults to ~/.cache/fastembed
|
|
|
|
# ============================================================
|
|
# Google OAuth2 (Google Workspace / .edu email accounts)
|
|
# ============================================================
|
|
# Required to use the "Connect with Google" OAuth flow in email account setup.
|
|
# Create credentials at: console.cloud.google.com → APIs & Services → Credentials
|
|
# 1. Enable the Gmail API for your project.
|
|
# 2. Configure the OAuth consent screen (User Type: Internal for Workspace orgs).
|
|
# Add scopes: https://mail.google.com/ and email.
|
|
# 3. Create an OAuth 2.0 Client ID (type: Web application).
|
|
# Add your redirect URI: http://localhost:7000/api/email/oauth/google/callback
|
|
# (replace host/port for hosted installs).
|
|
# 4. Copy the Client ID and Client Secret below.
|
|
#
|
|
# GOOGLE_OAUTH_CLIENT_ID=your-client-id.apps.googleusercontent.com
|
|
# GOOGLE_OAUTH_CLIENT_SECRET=replace-with-client-secret
|
|
#
|
|
# Set this explicitly for HTTPS, reverse-proxy, or hosted deployments. The
|
|
# value must exactly match an authorized redirect URI in the Google client.
|
|
# Local HTTP setups may use the callback URL inferred by the application.
|
|
# GOOGLE_OAUTH_REDIRECT_URI=https://your-domain.com/api/email/oauth/google/callback
|
|
|
|
# Origin the MCP OAuth callback is sent back to, for remote (Streamable HTTP)
|
|
# MCP servers that register it dynamically. Defaults to http://localhost:$APP_PORT,
|
|
# which is right only when you reach Odysseus directly on that port. Set it for
|
|
# HTTPS, reverse-proxy, hosted, and Docker installs — inside the container the
|
|
# app always listens on 7000 and cannot see the host port map, so the default is
|
|
# wrong there whenever APP_PORT is not 7000.
|
|
#
|
|
# Not for Google MCP servers. Those use Desktop App credentials, and Google only
|
|
# accepts loopback redirect URIs for that client type, so a public origin here is
|
|
# rejected with redirect_uri_mismatch. Leave it unset for a Google-only install:
|
|
# the loopback default is what Google wants, and remote users finish through the
|
|
# paste-back page, which never has to load the redirect.
|
|
# https://developers.google.com/identity/protocols/oauth2/native-app
|
|
# OAUTH_REDIRECT_BASE_URL=https://your-domain.com
|
|
|
|
# ============================================================
|
|
# Misc
|
|
# ============================================================
|
|
|
|
# Cleanup interval in hours (default: 24)
|
|
# CLEANUP_INTERVAL_HOURS=24
|
|
|
|
# In-process email pollers (default: on). Set to 0 if you're driving
|
|
# polling from cron / systemd via `scripts/odysseus-mail poll-scheduled`
|
|
# and `scripts/odysseus-mail poll-summary`, otherwise both schedulers
|
|
# race on the same SQLite.
|
|
# ODYSSEUS_INPROCESS_POLLERS=1
|
|
|
|
# In-process scheduled-task runner (default: on). Set to 0 to let an
|
|
# external driver fire scheduled tasks. Calendar reminders are
|
|
# frontend-driven (polling /api/notes from the browser) so no gate is
|
|
# needed there.
|
|
# ODYSSEUS_INPROCESS_TASKS=1
|
|
|
|
# Host used by the built-in "run_script" scheduled-task action.
|
|
# Empty/local/localhost runs scripts on the app host. Set to an SSH host alias
|
|
# if you intentionally want scheduled scripts to run remotely.
|
|
# ODYSSEUS_SCRIPT_HOST=localhost
|
|
|
|
# Chat / agent attachment size cap in bytes (default: 10 MB).
|
|
# Raise this for local installs that need larger PDFs or text documents.
|
|
# Example: 52428800 = 50 MB.
|
|
# ODYSSEUS_CHAT_UPLOAD_MAX_BYTES=10485760
|
|
|
|
# Other per-feature upload size caps in bytes. All are validated and optional;
|
|
# defaults shown. An invalid value (non-integer or < 1) fails fast at startup.
|
|
# ODYSSEUS_GALLERY_UPLOAD_MAX_BYTES=104857600 # gallery image upload (100 MB)
|
|
# ODYSSEUS_GALLERY_TRANSFORM_UPLOAD_MAX_BYTES=26214400 # gallery transform input (25 MB)
|
|
# ODYSSEUS_MEMORY_IMPORT_MAX_BYTES=10485760 # memory import file (10 MB)
|
|
# ODYSSEUS_PERSONAL_UPLOAD_MAX_BYTES=26214400 # personal document upload (25 MB)
|
|
# ODYSSEUS_EMAIL_COMPOSE_UPLOAD_MAX_BYTES=26214400 # email compose attachment (25 MB)
|
|
# ODYSSEUS_STT_MAX_AUDIO_BYTES=26214400 # speech-to-text audio (25 MB)
|
|
# ODYSSEUS_ICS_MAX_BYTES=10485760 # calendar .ics import (10 MB)
|
|
# ODYSSEUS_TTS_CACHE_MAX_BYTES=524288000 # TTS cache (500 MB)
|
|
|
|
# ============================================================
|
|
# Host Docker access (explicit opt-in)
|
|
# ============================================================
|
|
# Default Docker Compose does not mount /var/run/docker.sock. Existing
|
|
# Ollama, vLLM, and other OpenAI-compatible endpoints remain usable without it.
|
|
#
|
|
# Enable this only for intentional Cookbook/local Docker-daemon management.
|
|
# Raw socket access is high-trust and can grant broad control over the host
|
|
# Docker daemon. Set DOCKER_GID to the host docker group's numeric GID.
|
|
# Put these values in .env, or export them before running docker compose.
|
|
# COMPOSE_FILE=docker-compose.yml:docker/host-docker.yml
|
|
# DOCKER_GID=963
|
|
# docker/host-docker.yml sets this inside the container. Keep it paired
|
|
# with the socket overlay; setting it alone is not sufficient.
|
|
# ODYSSEUS_ENABLE_HOST_DOCKER=true
|
|
#
|
|
# Host Docker access can be combined with one GPU overlay:
|
|
# COMPOSE_FILE=docker-compose.yml:docker/gpu.nvidia.yml:docker/host-docker.yml
|
|
# COMPOSE_FILE=docker-compose.yml:docker/gpu.amd.yml:docker/host-docker.yml
|
|
|
|
# ============================================================
|
|
# GPU support (Docker Compose)
|
|
# ============================================================
|
|
# Pass the host GPU into the odysseus container. Default (unset) = CPU.
|
|
# COMPOSE_FILE is a native `docker compose` feature: a colon-separated
|
|
# list of files merged left-to-right. Pick ONE GPU line below, or leave
|
|
# all commented for CPU.
|
|
#
|
|
# NVIDIA (requires nvidia-container-toolkit + `nvidia-ctk runtime
|
|
# configure --runtime=docker` on the host):
|
|
# COMPOSE_FILE=docker-compose.yml:docker/gpu.nvidia.yml
|
|
# COMPOSE_FILE=docker-compose.yml;docker/gpu.nvidia.yml #(Windows)
|
|
#
|
|
# AMD ROCm (requires ROCm drivers on the host and the GID of the render group):
|
|
# COMPOSE_FILE=docker-compose.yml:docker/gpu.amd.yml
|
|
# Find the render GID with: getent group render | cut -d: -f3
|
|
# RENDER_GID=989
|
|
#
|
|
# These overlays only expose the GPU devices. The slim Odysseus image
|
|
# still needs CUDA/ROCm userspace via Cookbook -> Dependencies (vLLM,
|
|
# llama-cpp-python, etc.) before models can actually serve on GPU.
|
|
|
|
# ============================================================
|
|
# Storage Paths (Docker Compose)
|
|
# ============================================================
|
|
|
|
# APP_DATA_DIR=./data
|
|
# APP_LOGS_DIR=./logs
|