mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-06 06:52:20 +02:00
The configuration surface was undiscoverable. .env.example has three active
lines, and of the ODYSSEUS_* variables the code actually reads, most appear
nowhere in .env.example, docs/, website/ or README.md - including several that
change security-relevant behaviour (ODYSSEUS_BROWSER_NO_SANDBOX,
ODYSSEUS_ALLOW_PRIVATE_CALDAV, ODYSSEUS_ENABLE_HOST_DOCKER,
ODYSSEUS_MCP_ALLOWED_COMMANDS). Every question about one of them lands in the
issue tracker.
A hand-written page would drift within a month, so the page is generated:
- scripts/generate_env_reference.py walks the Python sources, collects each read
with the default it falls back to and the file it is read in, groups by area,
and marks the internal variables rather than omitting them.
- website/configuration-reference.md is the generated output, wired into the
Pages layout and linked from setup.md and .env.example. .env.example stays a
short deployment-level example and links onward rather than growing.
- tests/test_env_reference.py regenerates and compares, so adding a variable
without documenting it fails the suite. That is the point: the current state
happened because nothing objected.
Finding the reads needs more than one pattern. Two families - the upload caps in
src/upload_limits.py and the media-ingress overrides in src/media_ingress.py -
are read through helper functions, so the generator detects env-reader helpers
rather than hardcoding a list. Others span two lines, hold the variable name in
a module constant, or read through a mapping passed in as an argument. One lives
inside a string literal, in the Ollama probe script routes/cookbook_helpers.py
builds line by line. A line-based grep for os.environ.get("ODYSSEUS_ finds 70 of
the 98 the generator finds; the page reports that gap and recomputes it on every
run so the claim cannot go stale.
No application behaviour changes.
319 lines
15 KiB
Bash
319 lines
15 KiB
Bash
# Odysseus UI — Environment Configuration
|
|
# Copy this file to .env and fill in your values.
|
|
#
|
|
# This file stays deliberately short: it is for deployment-level overrides, and
|
|
# most runtime configuration belongs in Settings inside the app. For the complete
|
|
# list of ODYSSEUS_* variables the code reads, with the default each one falls
|
|
# back to, see website/configuration-reference.md (generated from the source).
|
|
|
|
# ============================================================
|
|
# 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
|
|
# ============================================================
|
|
|
|
# Optional backend workspace used automatically by the WebUI when no workspace
|
|
# is saved in the browser. This must be a directory visible to the backend;
|
|
# with host-workspace mapping, a host path is translated before vetting.
|
|
# ODYSSEUS_WORKSPACE_DEFAULT=/workspace/project
|
|
|
|
# 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=7011
|
|
|
|
# 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
|
|
|
|
# Skip the external-context exact-approval pause for unattended local agents.
|
|
# Keep false for shared or internet-exposed deployments.
|
|
|
|
# Optional post-external-context tool approval gate. Off by default because it
|
|
# can block normal agent work; enable only for deployments that want this fence.
|
|
# ODYSSEUS_TOOL_APPROVAL_GATE=0
|
|
|
|
# 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
|
|
|
|
# ============================================================
|
|
# Host workspace access (explicit opt-in)
|
|
# ============================================================
|
|
# Docker installs normally see only the container filesystem and /app/data.
|
|
# Enable this when the agent should edit a real host workspace like Codex.
|
|
# This is high-trust: the mounted tree is writable by the Odysseus container.
|
|
# COMPOSE_FILE=docker-compose.yml:docker/host-workspace.yml
|
|
# ODYSSEUS_HOST_WORKSPACE_DIR=/home/you
|
|
# ODYSSEUS_HOST_WORKSPACE_MOUNT=/host/workspace
|
|
#
|
|
# Host workspace access can be combined with host Docker access and GPU overlays:
|
|
# COMPOSE_FILE=docker-compose.yml:docker/host-workspace.yml:docker/host-docker.yml
|
|
|
|
# ============================================================
|
|
# Host network access (explicit opt-in, Linux Docker)
|
|
# ============================================================
|
|
# Docker bridge networking hides some host/LAN/VPN behavior from the agent:
|
|
# mDNS, some LAN discovery, local VPN/Tailscale state, and host namespace
|
|
# assumptions may differ from native Codex. Enable this only for high-trust
|
|
# local installs where the Odysseus container should share the host network.
|
|
#
|
|
# With host networking, Docker port publishing is disabled and the app listens
|
|
# directly on APP_PORT. The bundled SearXNG/Chroma services stay in Docker and
|
|
# are reached through their host-published loopback ports.
|
|
# COMPOSE_FILE=docker-compose.yml:docker/host-workspace.yml:docker/host-network.yml
|
|
# APP_BIND=127.0.0.1
|
|
# APP_PORT=7011
|
|
# ODYSSEUS_HOST_NETWORK_SEARXNG_INSTANCE=http://127.0.0.1:8080
|
|
# ODYSSEUS_HOST_NETWORK_CHROMADB_HOST=127.0.0.1
|
|
# ODYSSEUS_HOST_NETWORK_CHROMADB_PORT=8100
|
|
|
|
# ============================================================
|
|
# 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
|
|
# Maximum serialized layered photo-editor draft size (default: 256 MiB).
|
|
ODYSSEUS_EDITOR_DRAFT_MAX_BYTES=268435456
|