Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 20 additions & 14 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,10 @@ services:
# cuda / continuum-core-vulkan overlays) it's the actual ceiling.
mem_limit: ${CONTINUUM_CORE_MEM:-16g}
working_dir: /app
# depends_on does NOT include postgres — postgres is opt-in (profile),
# and by default continuum-core uses SQLite where no startup ordering
# matters. When users enable the postgres profile and set DATABASE_URL,
# Rust's PostgresAdapter (deadpool pool) retries connection on startup.
depends_on:
livekit-bridge:
condition: service_healthy
# No depends_on for services behind profiles (postgres, livekit-bridge).
# Core starts independently; connections to optional services (postgres
# pool, livekit bridge socket) retry on demand. Text chat works without
# any profile active — voice/video requires `--profile live`.
Comment on lines +88 to +90
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment says optional service connections (including the livekit-bridge socket) “retry on demand”, but continuum-core’s bridge client currently does a single UnixStream::connect() attempt and returns an error if the socket isn’t present; voice_register_session just logs that error and doesn’t retry. With --profile live, this can create a startup race where the first voice session fails if triggered before livekit-bridge finishes booting. Consider either (a) adjusting this comment to reflect the actual behavior (best-effort connect, may fail until bridge is up), or (b) adding a small retry/backoff around the initial bridge socket connect so voice can succeed immediately after stack startup.

Suggested change
# Core starts independently; connections to optional services (postgres
# pool, livekit bridge socket) retry on demand. Text chat works without
# any profile active — voice/video requires `--profile live`.
# Core starts independently; connections to optional services are
# best-effort at startup and may fail until those services are ready
# (for example, the livekit bridge socket when using `--profile live`).
# Text chat works without any profile active — voice/video requires
# `--profile live`.

Copilot uses AI. Check for mistakes.
volumes:
- voice-models:/app/models:ro
# Mount the ENTIRE ~/.continuum directory R/W. The Rust core reads config,
Expand Down Expand Up @@ -130,15 +127,18 @@ services:
# ── LiveKit Bridge (Rust — WebRTC transport adapter) ──────
# Links webrtc-sys but NOT ort. Separate process eliminates
# the protobuf symbol conflict that deadlocked continuum-core.
#
# Behind `live` profile: voice/video chat is opt-in. Text chat (the
# default first-chat experience) doesn't need LiveKit at all. This
# saves ~300MB RAM + 3 ports (7880-7882) for Carl's first run.
# Enable with: docker compose --profile live up
livekit-bridge:
profiles: [live]
build:
context: ./src/workers
dockerfile: ../../docker/livekit-bridge.Dockerfile
image: ghcr.io/cambriantech/continuum-livekit-bridge:${CONTINUUM_IMAGE_TAG:-latest}
restart: unless-stopped
# WebRTC encode/decode buffers + multi-stream. Scales with host RAM —
# install.sh sets LIVEKIT_BRIDGE_MEM to max(2, host_gb/8). Default 2g
# for manual docker compose users; install.sh writes the calculated one.
mem_limit: ${LIVEKIT_BRIDGE_MEM:-2g}
depends_on:
- livekit
Expand Down Expand Up @@ -184,7 +184,12 @@ services:
- NODE_ENV=production
- JTAG_SKIP_HTTP=1
- JTAG_NO_TLS=1
- LIVEKIT_URL=${LIVEKIT_BROWSER_URL:-ws://livekit:7880}
# Browser connects to LiveKit via host-mapped port, not Docker DNS.
# 'ws://livekit:7880' only resolves inside the Docker network;
# the browser runs on the host where 'livekit' doesn't resolve.
# localhost:7880 works because livekit binds that port to the host.
# Grid mode overrides via LIVEKIT_BROWSER_URL=ws://tailscale:7880.
- LIVEKIT_URL=${LIVEKIT_BROWSER_URL:-ws://localhost:7880}

# ── Widget Server (Vite) ──────────────────────────────────
widget-server:
Expand All @@ -208,10 +213,11 @@ services:
- JTAG_WS_PROXY_PORT=9001

# ── LiveKit (WebRTC) — local mode ───────────────────────────
# Dev server for local development. Always starts.
# In grid mode, set LIVEKIT_HOST_PORT=0 in .env to avoid port conflict with tailscale.
# (LiveKit still runs but on unmapped ports — harmless, ~50MB RAM.)
# Dev server for voice/video. Behind `live` profile — text chat doesn't
# need it. In grid mode, set LIVEKIT_HOST_PORT=0 to avoid port conflict.
# Enable with: docker compose --profile live up
livekit:
profiles: [live]
image: livekit/livekit-server:latest
restart: unless-stopped
mem_limit: 256m
Expand Down
Loading