Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
227 commits
Select commit Hold shift + click to select a range
f19a2d6
Batch 1: Apply vision+windows fixes
Jun 10, 2026
1378905
Batch 2: Apply auth+email+task fixes
Jun 10, 2026
277b45a
Batch 3: Apply hwfit+codenav+settings+tour fixes
Jun 10, 2026
6aa8b34
Batch 4: Apply agent+cookbook fixes (partial)
Jun 10, 2026
41325e7
Batch 5a: Apply PRs #3663, #3661, #3658 (skipped #3665 failed on src/…
Jun 10, 2026
acaadef
Batch 5d: Apply PRs #3617, #3606; skipped #3616, #3615, #3614 (failed…
Jun 10, 2026
f5f6eb9
Batch 5b: Apply PRs #3657, #3649, #3647, #3641, #3640
Jun 10, 2026
caf732f
Batch 5c: Apply PRs #3639, #3638, #3637, #3622, #3618
Jun 10, 2026
a55ee80
Batch 5e: Apply PRs #3601, #3600, #3597, #3584, #3580
Jun 10, 2026
152ca82
Batch 5g: Apply PRs #3558, #3549, #3548, #3544, #3541
Jun 10, 2026
252ad10
Batch 5j: Apply PRs #3503, #3499, #3495, #3486 (#3504 failed to apply)
Jun 10, 2026
f3cee57
Batch 5i: Apply PRs #3516, #3515, #3513, #3508, #3506
Jun 10, 2026
b6e365d
Batch 5h: Apply PRs #3539, #3538, #3537, #3532, #3521
gunnarwrld Jun 8, 2026
5aba3fd
Batch 5k: Apply PRs #3484, #3480, #3479, #3469, #3468
Jun 10, 2026
2c90cef
Batch 5l: Apply PRs #3462, #3453, #3452, #3451 (#3459 failed to apply)
Jun 10, 2026
5fec8ac
Batch 5m: Apply PRs #3434, #3428, #3424, #3421 (#3429 failed to apply)
Jun 10, 2026
7025915
fix(cookbook): resolve conflict for PR #3689 (NVIDIA CUDA Docker supp…
Jun 10, 2026
1f371a8
refactor(constants): resolve conflict for PR #3678 (remove core/const…
Jun 10, 2026
3c648ae
feat(launcher): resolve conflict for PR #3660 (unified Windows launch…
Jun 10, 2026
39caa67
feat(agent): resolve conflict for PR #3665 (confine agent file/shell …
Jun 10, 2026
7839633
refactor(tools): resolve conflict for PR #3666 (extract document tool…
Jun 10, 2026
80208d8
fix: resolve conflicts for PRs #3615, #3504, #3429 (model context, se…
Jun 10, 2026
c675c37
apply PR #3730
Jun 10, 2026
1d6938a
apply PR #3710
Jun 10, 2026
c511cb4
apply PRs batch: #3381, #3370, #3357
Jun 10, 2026
441d9a0
apply PRs batch: #3352, #3340, #3321, #3315, #3314
Jun 10, 2026
20557eb
apply PRs batch: #3310, #3291, #3290, #3288
Jun 10, 2026
5265bf4
apply PR #3249
Jun 10, 2026
2293da7
apply PR #3172
Jun 10, 2026
3f801b6
apply PRs batch: #3169, #3161
Jun 10, 2026
0beb84f
apply PRs batch: #3150, #3146, #3143
Jun 10, 2026
fc4897a
apply PR #3134
Jun 10, 2026
128888e
apply PR #2865: docs(readme): add packaging status
Jun 10, 2026
e0d17af
apply PR #2820: fix(research): scope Clear all to its section
Jun 10, 2026
77b6408
apply PRs batch: #3097, #3093, #3090
Jun 10, 2026
7976b08
apply PR #2903
Jun 10, 2026
2c9e0f1
apply PR #2894
Jun 10, 2026
7ccaa7b
apply PR #3078
Jun 10, 2026
1903b15
apply PR #3175
Jun 10, 2026
c9fa8be
apply PR #3128
Jun 10, 2026
856d5df
apply PR #3115
Jun 10, 2026
17d6a4f
apply PR #3572: fix(skills): open editor from latest test view
Jun 10, 2026
1c0edf7
apply PR #3107
Jun 10, 2026
49c8a34
apply PR #3102
Jun 10, 2026
1209ec5
apply PR #3408
Jun 10, 2026
5d67510
apply PR #3418: fix(windows): resolve background task crashes
Jun 10, 2026
fc60c7f
apply PR #3283: fix(calendar): honor list_events date range aliases
Jun 10, 2026
3714b95
apply PR #3281: fix: read allow_bash/allow_web_search from JSON body
Jun 10, 2026
781729c
apply PR #3259: feat(workspace): add git workflow backend APIs
Jun 10, 2026
a62c218
apply PR #2559
Jun 10, 2026
f95e035
apply PR #3384, #3265
Jun 10, 2026
8b313a8
apply PR #2732
Jun 10, 2026
d5f72df
apply PR #2727
Jun 10, 2026
b79a397
apply PR #2707
Jun 10, 2026
8cd616f
apply PR #2694
Jun 10, 2026
2325473
apply PR #2693
Jun 10, 2026
e37e4ba
apply PR #2622
Jun 10, 2026
c411ca3
apply PR #2587
Jun 10, 2026
d5b4672
apply PR #2579
Jun 10, 2026
6ab7233
apply PR #2575
Jun 10, 2026
6227a8c
apply PR #2568
Jun 10, 2026
a8e4e02
apply PR #2564
Jun 10, 2026
d1b70b2
apply PR #2405
Jun 10, 2026
9634615
apply PR #2402
Jun 10, 2026
064dbd3
apply PR #2379
Jun 10, 2026
c500739
fix: preserve pending email expand
5p00kyy Jun 6, 2026
dd26f21
fix(mcp): forward env headers for SSE and Streamable HTTP transports
Jun 5, 2026
1d7c879
apply PR #3215, #3212, #3208, #3206
Jun 10, 2026
a73a4e3
apply PR #2397: bug report template: add source guardrail + commit SH…
Jun 10, 2026
5eea399
apply PR #2560: add macOS background service via launchd (service-mac…
Jun 10, 2026
8b9017c
apply PR #2417: fix(agent): fail fast when model never streams a token
Jun 10, 2026
e528831
apply PR #3016, #3019, #3015, #3011, #2983
Jun 10, 2026
239981c
apply PR #3117, #3095, #3059
Jun 10, 2026
a548abf
apply PR #2372: fix(llm): harden SSE parser against malformed stream …
Jun 10, 2026
28afedb
apply PR #2383: feat(ui): add i18n support with language switcher
Jun 10, 2026
576e63d
apply PR #2149
Jun 10, 2026
8bdb14e
apply PR #2143
Jun 10, 2026
307d9ee
apply PR #2126
Jun 10, 2026
3fa00d0
apply PR #2113
Jun 10, 2026
ece46c9
fix: hwfit params_b/is_prequantized crash on non-string
Jun 10, 2026
30e0cc6
fix: odysseus-memory cmd_add crashes on non-dict existing
Jun 10, 2026
3c6837f
Fix research endpoint model selection ignoring pinned model
Jun 10, 2026
225b3a7
Fix task run endpoint resolution ignoring pinned model IDs
Jun 10, 2026
836777f
[PATCH 1/9] Add crabbox.sh: run Odysseus on a throwaway islo.dev box
Jun 10, 2026
626c043
Fix /api/default-chat preselecting a non-chat model as the
Jun 10, 2026
7ea7bb7
[PATCH 1/2] Fix odysseus-gallery list --tag ignoring ai_tags and tag
Jun 10, 2026
fa92ea5
Fix odysseus-mail list not ordering messages newest-first by
Jun 10, 2026
8f40b13
[PATCH 1/2] Fix odysseus-docs search returning nothing for multi-word
Jun 10, 2026
276d2a8
Fix odysseus-calendar list dropping in-progress / multi-day
Jun 10, 2026
a62f799
Fix _parse_msg_content corrupting JSON-array-like text
Jun 10, 2026
449aa78
Apply PR #1392: fix(ui): use raw data for comparison export to avoid …
Jun 10, 2026
53d43de
Apply PR #1377: docs: document Cookbook pip cache relocation
Jun 10, 2026
2ae3f3b
apply PR #1882
Jun 10, 2026
fd3da2c
apply PR #1881
Jun 10, 2026
68a1dbb
apply PR #1880
Jun 10, 2026
ba2d043
apply PR #1879
Jun 10, 2026
c31a4c4
apply PR #1877
Jun 10, 2026
c7ebfa9
apply PR #1875
Jun 10, 2026
451e29e
apply PR #1874
Jun 10, 2026
23635f0
apply PR #1873
Jun 10, 2026
cc8998c
apply PR #1870
Jun 10, 2026
1fca4b3
apply PR #1868
Jun 10, 2026
935ce02
apply PR #2368
Jun 10, 2026
d486443
apply PR #2336
Jun 10, 2026
015d68b
apply PR #2329
Jun 10, 2026
70fc5c6
apply PR #2307
Jun 10, 2026
f64a58a
apply PR #2296
Jun 10, 2026
e82f10b
apply PR #2294
Jun 10, 2026
ce25f86
apply PR #2282
Jun 10, 2026
162392a
apply PR #2281
Jun 10, 2026
03a1b37
apply PR #2260
Jun 10, 2026
fa28d62
apply PR #2226
Jun 10, 2026
c7442db
Apply PR #428: pwa missing icons added
Jun 10, 2026
85c4c04
apply PR #2370
Jun 10, 2026
9f0b775
fix: grant checkout contents permission in description workflows
Jun 10, 2026
6908ef5
Fix empty-session model recovery ignoring pinned-only endpoints
Jun 10, 2026
3585aa0
fix: resolve merge conflict artifacts in skills_routes, skill_from_do…
Jun 10, 2026
f81d8e4
Apply PR #3737
Jun 10, 2026
bddc379
Apply PR #3404
Jun 10, 2026
6010355
Apply PR #3393
Jun 10, 2026
e0f326b
Apply PR #3390
Jun 10, 2026
55061ef
Apply PR #3193
Jun 10, 2026
c5c94c4
Apply PR #3030
Jun 10, 2026
1f15f01
Apply PR #2805
Jun 10, 2026
7519db5
Apply PR #2747
Jun 10, 2026
0e414d7
Apply PR #2681
Jun 10, 2026
7b74882
Apply PR #2371
Jun 10, 2026
b138668
Apply PR #2328
Jun 10, 2026
6b885ef
Apply PR #2292
Jun 10, 2026
01ea382
Apply PR #2118
Jun 10, 2026
84c2ba8
Apply PR #2077
Jun 10, 2026
b58d3ea
Apply PR #2017
Jun 10, 2026
ec03cc5
Apply PR #2014
Jun 10, 2026
f741357
Apply PR #2007
Jun 10, 2026
d74e1d9
Apply PR #2006
Jun 10, 2026
3bfa127
Apply PR #2005
Jun 10, 2026
17d05ce
Apply PR #2003
Jun 10, 2026
dee4343
Apply PR #2002
Jun 10, 2026
7179183
Apply PR #1971
Jun 10, 2026
74ff0c1
Apply PR #1945
Jun 10, 2026
d127427
Apply PR #1942
Jun 10, 2026
9e81795
Apply PR #1869
Jun 10, 2026
cdb81dc
Apply PR #1839
Jun 10, 2026
1cd8d41
Apply PR #1838
Jun 10, 2026
c8c0e95
Apply PR #1836
Jun 10, 2026
4803f92
Apply PR #1835
Jun 10, 2026
41ba18b
Apply PR #1832
Jun 10, 2026
9a9af46
Apply PR #1831
Jun 10, 2026
4cd8b50
Apply PR #1829
Jun 10, 2026
cf902a6
Apply PR #1828
Jun 10, 2026
29ca865
Apply PR #1827
Jun 10, 2026
81a4181
Apply PR #1826
Jun 10, 2026
cd99737
Apply PR #1824
Jun 10, 2026
9f7090b
Apply PR #1819
Jun 10, 2026
4cc18fd
Apply PR #1775
Jun 10, 2026
9ddfba8
Apply PR #1576
Jun 10, 2026
0007beb
Apply PR #1575
Jun 10, 2026
4f76aa6
Apply PR #1564
Jun 10, 2026
45cc096
Apply PR #1536
Jun 10, 2026
227061d
Apply PR #1506
Jun 10, 2026
9794b15
Apply PR #1454
Jun 10, 2026
d8a5d50
Apply PR #1384
Jun 10, 2026
617bceb
Apply PR #1376
Jun 10, 2026
956cb20
Apply PR #1339
Jun 10, 2026
ab7a4dd
Apply PR #1293
Jun 10, 2026
deb2f1b
Apply PR #1221
Jun 10, 2026
73413fd
Apply PR #1096
Jun 10, 2026
3cc5e79
Apply PR #1092
Jun 10, 2026
1f3a3d0
Apply PR #565
Jun 10, 2026
a0fcfa8
Apply PR #544
Jun 10, 2026
f03e4be
Apply PR #427
Jun 10, 2026
61f9f88
Apply PR #406
Jun 10, 2026
841e260
Apply PR #319
Jun 10, 2026
a40d227
Apply PR #2981
Jun 10, 2026
35cfc10
Apply PR #2977
Jun 10, 2026
c074f34
Apply PR #2920
Jun 10, 2026
bacbb94
Apply PR #2802
Jun 10, 2026
e763c49
Apply PR #2796
Jun 10, 2026
80b42b4
Apply PR #2778
Jun 10, 2026
e12f997
Apply PR #2544
Jun 10, 2026
d1b67d8
Apply PR #2538
Jun 10, 2026
6878eeb
Apply PR #2519
Jun 10, 2026
d673106
Apply PR #2440
Jun 10, 2026
aa291f0
Apply PR #2422
Jun 10, 2026
aaa8226
Apply PR #2047
Jun 10, 2026
9ccd436
Apply PR #2045
Jun 10, 2026
6208f96
Apply PR #2042
Jun 10, 2026
cc16fbc
Apply PR #2034
Jun 10, 2026
e563c0a
Apply PR #2032
Jun 10, 2026
2e941bc
Apply PR #2031
Jun 10, 2026
c4cf9f0
Apply PR #2029
Jun 10, 2026
ba82314
Apply PR #1973
Jun 10, 2026
3524968
Apply PR #1960
Jun 10, 2026
2118653
Apply PR #1926
Jun 10, 2026
c207471
Apply PR #1925
Jun 10, 2026
834a455
Apply PR #1920
Jun 10, 2026
2ab53c5
Apply PR #1911
Jun 10, 2026
7a1e418
Apply PR #1910
Jun 10, 2026
f86cdd2
Apply PR #1909
Jun 10, 2026
b6344b4
Apply PR #1907
Jun 10, 2026
5588303
Apply PR #1905
Jun 10, 2026
81dba13
Apply PR #1904
Jun 10, 2026
b7ae51a
Apply PR #1899
Jun 10, 2026
610a0bc
Apply PR #1897
Jun 10, 2026
68485f3
Apply PR #1895
Jun 10, 2026
5ebdf81
Apply PR #1891
Jun 10, 2026
52fbb14
Apply PR #1890
Jun 10, 2026
efd83b1
Apply PR #1888
Jun 10, 2026
51849fa
Apply PR #1887
Jun 10, 2026
53f207e
Apply PR #1886
Jun 10, 2026
0deb449
Apply PR #1876
Jun 10, 2026
bf9896a
Apply PR #1830
Jun 10, 2026
90421cb
Apply PR #1825
Jun 10, 2026
932699b
Apply PR #1807
Jun 10, 2026
865fb55
Apply PR #1805
Jun 10, 2026
32d2666
Apply PR #1766
Jun 10, 2026
1ab9cd1
Apply PR #1684
Jun 10, 2026
23234b9
Apply PR #1629
Jun 10, 2026
6a19382
Apply PR #1590
Jun 10, 2026
f909ed5
Apply PR #1489
Jun 10, 2026
136005f
Apply PR #1485
Jun 10, 2026
f38fd74
fix all remaining test failures: double-shift, workflow permissions, …
Jun 10, 2026
b5bc5bf
apply all open PRs, fix test regressions, and align sanitizer/thinkin…
Jun 11, 2026
fbf5895
Merge branch 'origin/dev' into fix/apply-all-open-prs to resolve conf…
Jun 11, 2026
a4e082f
Restore cookbook helper and route changes to fix endpoint probing tes…
Jun 11, 2026
b645cbb
docs: add completed pull request description
Jun 11, 2026
5541d34
ci: relax PR title checks to support case-insensitive and slash separ…
Jun 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
158 changes: 158 additions & 0 deletions .devcontainer/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
# Odysseus UI — Dev Container environment
# Copy this file to .devcontainer/.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

# 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

# ============================================================
# 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

# Development-only auth bypass for loopback requests.
# Keep false for Docker, LAN, reverse proxy, and any shared deployment.
# LOCALHOST_BYPASS=false

# 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 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

# ============================================================
# 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

# ============================================================
# 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
# RENDER_GID=992
#
# 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.
12 changes: 12 additions & 0 deletions .devcontainer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Dev Containers

## What is a Devcontainer?

A devcontainer runs Odysseus and its project files inside Docker so your editor, terminal, and app all live in the same Linux environment. You can use it from any IDE with Dev Containers support — VS Code, Cursor, and similar editors. It will deploy Odysseus plus ChromaDB, SearXNG, and ntfy — with code reload while you edit. Pick **Ubuntu** or **Fedora** when you open the folder in a container.

## Setup

1. Copy `.devcontainer/.env.example` to `.devcontainer/.env`.
2. Copy the profile env too: `ubuntu/.env.example` → `ubuntu/.env` (or `fedora/` for Fedora).
3. In VS Code, Cursor, or another supported IDE: **Dev Containers: Open Folder in Container** — choose Ubuntu or Fedora.
4. Open `http://localhost:7000`. First boot prints an admin password in the logs.
80 changes: 80 additions & 0 deletions .devcontainer/docker-compose.dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Shared Dev Container sidecar stack (no odysseus — each profile defines its own).
# Env: .devcontainer/.env only (not repo-root .env).
services:
chromadb:
image: docker.io/chromadb/chroma:latest
ports:
- "${CHROMADB_BIND:-127.0.0.1}:8100:8000"
volumes:
- chromadb-data:/chroma/chroma
environment:
- ANONYMIZED_TELEMETRY=FALSE
env_file:
- .env
networks:
- odysseus-dev
restart: unless-stopped

searxng:
# Pinned, not :latest — odysseus waits on searxng's healthcheck
# (depends_on: condition: service_healthy), so a broken upstream `latest`
# tag blocks the whole app from starting. 2026.6.2 crashes on boot with
# `KeyError: 'default_doi_resolver'`, failing the healthcheck (issue #1414).
# Bump this deliberately after verifying a newer tag boots clean.
image: docker.io/searxng/searxng:2026.5.31-7159b8aed
entrypoint:
- /bin/sh
- -c
- |
set -eu
if [ ! -s /etc/searxng/settings.yml ] || grep -q 'odysseus-local-searxng-json-2026-05-30\|__SEARXNG_SECRET__' /etc/searxng/settings.yml; then
secret="$${SEARXNG_SECRET:-}"
if [ -z "$$secret" ]; then
secret="$$(python -c 'import secrets; print(secrets.token_urlsafe(48))')"
fi
sed "s|__SEARXNG_SECRET__|$$secret|g" /tmp/searxng-settings.yml.template > /etc/searxng/settings.yml
fi
exec /usr/local/searxng/entrypoint.sh
ports:
- "127.0.0.1:8080:8080"
volumes:
- searxng-data:/etc/searxng
- ../config/searxng/settings.yml:/tmp/searxng-settings.yml.template:ro
environment:
- SEARXNG_BASE_URL=http://localhost:8080/
- SEARXNG_SECRET=${SEARXNG_SECRET:-}
env_file:
- .env
healthcheck:
test: ["CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:8080/', timeout=5).read(1)\""]
interval: 5s
timeout: 6s
retries: 20
start_period: 10s
networks:
- odysseus-dev
restart: unless-stopped

ntfy:
image: docker.io/binwiederhier/ntfy
command: serve
ports:
- "${NTFY_BIND:-127.0.0.1}:8091:80"
volumes:
- ntfy-cache:/var/cache/ntfy
environment:
- NTFY_BASE_URL=${NTFY_BASE_URL:-http://localhost:8091}
env_file:
- .env
networks:
- odysseus-dev
restart: unless-stopped

networks:
odysseus-dev:
driver: bridge

volumes:
searxng-data:
chromadb-data:
ntfy-cache:
21 changes: 21 additions & 0 deletions .devcontainer/fedora/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Odysseus Dev Container — Fedora profile
# Copy to .devcontainer/fedora/.env

# Match the container drop-user to your host UID/GID so bind-mounted
# ./data and ./logs stay editable from the host.
# Find yours with: id -u / id -g
PUID=1000
PGID=1000

# SELinux: fedora/docker-compose.yml adds :z on data/log bind mounts so
# Enforcing hosts can write to ./data and ./logs from inside the container.

# GPU overlay — NVIDIA (requires nvidia-container-toolkit on the Fedora host):
# sudo dnf install nvidia-container-toolkit
# sudo nvidia-ctk runtime configure --runtime=docker
# sudo systemctl restart docker
# COMPOSE_FILE=.devcontainer/docker-compose.dev.yml:.devcontainer/fedora/docker-compose.yml:docker/gpu.nvidia.yml

# GPU overlay — AMD ROCm (requires ROCm drivers and render group GID):
# COMPOSE_FILE=.devcontainer/docker-compose.dev.yml:.devcontainer/fedora/docker-compose.yml:docker/gpu.amd.yml
# RENDER_GID=992
43 changes: 43 additions & 0 deletions .devcontainer/fedora/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
FROM fedora:41

ENV PIP_BREAK_SYSTEM_PACKAGES=1

# System deps mirror the production Dockerfile; gosu is installed from upstream
# because Fedora does not ship it in the base repos.
RUN dnf install -y \
python3.12 \
python3.12-devel \
gcc \
gcc-c++ \
make \
cmake \
git \
nodejs \
npm \
tmux \
openssh-clients \
&& dnf clean all \
&& ln -sf /usr/bin/python3.12 /usr/bin/python3 \
&& ln -sf /usr/bin/python3.12 /usr/bin/python \
&& python3.12 -m ensurepip --upgrade

RUN curl -fsSL -o /usr/local/bin/gosu \
"https://github.com/tianon/gosu/releases/download/1.17/gosu-amd64" \
&& chmod +x /usr/local/bin/gosu

WORKDIR /app

COPY requirements.txt .
RUN python3 -m pip install --no-cache-dir -r requirements.txt

COPY . .

RUN mkdir -p data logs services/cache/search

COPY docker/entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh

EXPOSE 7000

ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7000"]
18 changes: 18 additions & 0 deletions .devcontainer/fedora/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "Odysseus (Fedora)",
"dockerComposeFile": [
"../docker-compose.dev.yml",
"docker-compose.yml"
],
"service": "odysseus",
"workspaceFolder": "/app",
"remoteUser": "root",
"postCreateCommand": "python setup.py",
"customizations": {
"vscode": {
"settings": {
"python.defaultInterpreterPath": "/usr/bin/python3"
}
}
}
}
34 changes: 34 additions & 0 deletions .devcontainer/fedora/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
services:
odysseus:
build:
context: ../
dockerfile: .devcontainer/fedora/Dockerfile
ports:
- "${APP_BIND:-127.0.0.1}:${APP_PORT:-7000}:7000"
volumes:
- ../:/app:cached
- ../data:/app/data:z
- ../logs:/app/logs:z
- ../data/ssh:/app/.ssh:z
- ../data/huggingface:/app/.cache/huggingface:z
- ../data/local:/app/.local:z
extra_hosts:
- "host.docker.internal:host-gateway"
env_file:
- .env
- ./fedora/.env
environment:
- SEARXNG_INSTANCE=http://searxng:8080
- CHROMADB_HOST=chromadb
- CHROMADB_PORT=8000
- PUID=${PUID:-1000}
- PGID=${PGID:-1000}
command: uvicorn app:app --host 0.0.0.0 --port 7000 --reload
depends_on:
searxng:
condition: service_healthy
chromadb:
condition: service_started
networks:
- odysseus-dev
restart: unless-stopped
14 changes: 14 additions & 0 deletions .devcontainer/ubuntu/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Odysseus Dev Container — Ubuntu profile
# Copy to .devcontainer/ubuntu/.env

# Match the container drop-user to your host UID/GID so bind-mounted
# ./data and ./logs stay editable from the host.
# Find yours with: id -u / id -g
PUID=1000
PGID=1000

# GPU overlay (requires nvidia-container-toolkit on the Ubuntu host):
# sudo apt install nvidia-container-toolkit
# sudo nvidia-ctk runtime configure --runtime=docker
# sudo systemctl restart docker
# COMPOSE_FILE=.devcontainer/docker-compose.dev.yml:.devcontainer/ubuntu/docker-compose.yml:docker/gpu.nvidia.yml
Loading
Loading