diff --git a/.env.example b/.env.example index 0873b18..39acb3a 100644 --- a/.env.example +++ b/.env.example @@ -152,3 +152,38 @@ SCREENSHOT_INTERVAL_SEC=5 # --------------------------------------------------------------------------- # Silence (ms) that marks the end of an utterance before sending to the brain. VOICE_SILENCE_MS=800 + +# =========================================================================== +# Split deployment & cross-platform (Ubuntu + Windows 11) +# =========================================================================== +# JARVIS_ROLE selects what this machine runs (see docker/run-if-role.sh): +# full (default) everything in one container +# browser ONLY the desktop + Chrome + control-server (driven over the LAN) +# bot ONLY the bot + bridge + TTS (drives a REMOTE browser) +JARVIS_ROLE=full + +# --- GPU per OS: pick the matching compose override via COMPOSE_FILE --- +# Ubuntu (nvidia-container-toolkit / CDI): +# COMPOSE_FILE=docker-compose.yml:docker-compose.gpu-linux.yml +# Windows 11 (Docker Desktop + WSL2 + NVIDIA): +# COMPOSE_FILE=docker-compose.yml:docker-compose.gpu-windows.yml +# Browser-only host (no GPU needed): leave COMPOSE_FILE unset (base only). +COMPOSE_FILE=docker-compose.yml:docker-compose.gpu-linux.yml + +# --- Browser HOST (JARVIS_ROLE=browser) — e.g. this LAN machine --- +# Expose Chrome control to the internal network (no auth, internal only): +# CDP_BIND=0.0.0.0 +# BROWSER_CONTROL_BIND=0.0.0.0 +# CDP_PUBLISH_BIND=0.0.0.0 +# Defaults are loopback-only. + +# --- BOT host (JARVIS_ROLE=bot) — e.g. your PC driving the remote browser --- +# Point the controlBrowser tool at the browser host's control-server: +# BROWSER_CONTROL_URL=http://192.168.10.9:8777 +# (Leave BROWSER_CONTROL_URL empty on full/browser layouts.) + +# --- Models (tune per machine) --- +# OLLAMA_CHAT_MODEL=qwen2.5:7b # quality (needs ~5GB VRAM + whisper small) +# OLLAMA_CHAT_MODEL=qwen2.5:3b # speed (fits easily, faster on 8GB GPUs) +# WHISPER_MODEL=small # small frees VRAM for a bigger LLM; medium=more accurate +# MELO_DEVICE=cuda # cpu if no GPU on the bot host diff --git a/docker-compose.gpu-linux.yml b/docker-compose.gpu-linux.yml new file mode 100644 index 0000000..5fdeed2 --- /dev/null +++ b/docker-compose.gpu-linux.yml @@ -0,0 +1,14 @@ +# GPU override for LINUX hosts using nvidia-container-toolkit with CDI +# (Ubuntu local Docker). Verified on the RTX 5050 (Blackwell sm_120). +# +# docker compose -f docker-compose.yml -f docker-compose.gpu-linux.yml up -d +# +# Or set COMPOSE_FILE in .env (recommended): +# COMPOSE_FILE=docker-compose.yml:docker-compose.gpu-linux.yml +services: + ollama: + devices: + - "nvidia.com/gpu=all" + javis: + devices: + - "nvidia.com/gpu=all" diff --git a/docker-compose.gpu-windows.yml b/docker-compose.gpu-windows.yml new file mode 100644 index 0000000..039165f --- /dev/null +++ b/docker-compose.gpu-windows.yml @@ -0,0 +1,26 @@ +# GPU override for WINDOWS 11 (Docker Desktop + WSL2 + NVIDIA) and any host +# that exposes the GPU through Docker's portable device-reservation API rather +# than CDI. Requires the NVIDIA GPU driver on Windows and GPU support enabled in +# Docker Desktop (Settings → Resources → WSL Integration / GPU). +# +# docker compose -f docker-compose.yml -f docker-compose.gpu-windows.yml up -d +# +# Or set COMPOSE_FILE in .env (recommended): +# COMPOSE_FILE=docker-compose.yml:docker-compose.gpu-windows.yml +services: + ollama: + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: all + capabilities: [gpu] + javis: + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: all + capabilities: [gpu] diff --git a/docker-compose.yml b/docker-compose.yml index ecec0be..c76a0fb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -27,10 +27,9 @@ services: # model resident forever, wasting VRAM next to the chat model. volumes: - ollama_models:/root/.ollama - # GPU: needs nvidia-container-toolkit on the host (CDI). Verified on the - # RTX 5050 (Blackwell sm_120) — Ollama offloads 100% to GPU. - devices: - - "nvidia.com/gpu=all" + # GPU is added by a platform override (see docker-compose.gpu-linux.yml / + # docker-compose.gpu-windows.yml + COMPOSE_FILE in .env). Base stays + # GPU-agnostic so the same files run on Ubuntu (CDI) and Windows (Desktop). # Auto-pull the models the brain needs, then exit. Idempotent (re-runnable). ollama-init: @@ -102,10 +101,8 @@ services: # must NOT pull in Ollama. Full/bot layouts start it with a plain # `docker compose up -d` (all services); the bridge tolerates Ollama warming # up lazily, so start order doesn't matter. - # GPU: accelerates Whisper STT (and anything else CUDA) in this container. - # Verified: faster-whisper float16 works on the RTX 5050 (sm_120). - devices: - - "nvidia.com/gpu=all" + # GPU is added by a platform override (docker-compose.gpu-linux.yml / + # docker-compose.gpu-windows.yml). The browser-only host needs no GPU. shm_size: "1gb" # Chrome needs a larger /dev/shm ports: # All published to loopback only by default — VNC/noVNC use a weak default diff --git a/docs/DEPLOY.md b/docs/DEPLOY.md new file mode 100644 index 0000000..691e89d --- /dev/null +++ b/docs/DEPLOY.md @@ -0,0 +1,73 @@ +# Deployment layouts + +One image, three roles (`JARVIS_ROLE`), selected in `.env`. GPU is added per OS +via a compose override picked with `COMPOSE_FILE`. + +## A. All-in-one (single machine) + +Everything (desktop + Chrome + bridge + bot + TTS) in one container. + +``` +# .env +JARVIS_ROLE=full +COMPOSE_FILE=docker-compose.yml:docker-compose.gpu-linux.yml # Ubuntu +# COMPOSE_FILE=docker-compose.yml:docker-compose.gpu-windows.yml # Windows 11 +DISCORD_SELFBOT_TOKEN=... +DISCORD_GUILD_ID=... + +docker compose up -d # Ollama + javis (COMPOSE_FILE adds GPU) +``` + +## B. Split: browser host (LAN) + bot on your PC + +The on-screen Chrome, real mouse/keyboard (xdotool) and screen live on the +**browser host**. Your PC runs the **bot** and drives that browser over the +internal network — no auth (internal only). + +### Browser host (the LAN machine that shows Chrome, e.g. 192.168.10.9) + +``` +# .env +JARVIS_ROLE=browser +CDP_BIND=0.0.0.0 +BROWSER_CONTROL_BIND=0.0.0.0 +CDP_PUBLISH_BIND=0.0.0.0 +# no GPU needed → leave COMPOSE_FILE unset (base compose only) + +docker compose up -d javis # desktop + Chrome + control-server (port 8777) +``` + +Watch it on this machine’s VNC (`localhost:5901`) / noVNC (`localhost:6080`). + +### Bot host (your PC — Ubuntu or Windows 11) + +``` +# .env +JARVIS_ROLE=bot +BROWSER_CONTROL_URL=http://192.168.10.9:8777 # the browser host's LAN IP +COMPOSE_FILE=docker-compose.yml:docker-compose.gpu-linux.yml # Ubuntu +# COMPOSE_FILE=docker-compose.yml:docker-compose.gpu-windows.yml # Windows 11 +DISCORD_SELFBOT_TOKEN=... +DISCORD_GUILD_ID=... + +docker compose up -d # bot + bridge + TTS + Ollama (GPU per OS) +``` + +The bot’s `controlBrowser` tool posts commands to `BROWSER_CONTROL_URL`, so +"네이버에서 X 검색", "구글로 돌아가" etc. drive the **browser host’s** Chrome with real +human-style input (visible on its VNC). + +## Windows 11 notes + +- Install the NVIDIA driver on Windows and enable GPU in Docker Desktop + (Settings → Resources → WSL Integration). Use the `gpu-windows.yml` override. +- Paths: named volumes are cross-platform. The Gemini OAuth bind mount defaults + to `${HOME}/.config/javis/gemini` (works under WSL); override `GEMINI_OAUTH_DIR` + if needed. + +## Known limitation + +Discord Go-Live broadcast of the **browser host's** screen from a **remote** bot +is not supported (the bot's WebRTC screen capture is local to the bot machine). +Use the browser host's VNC to view it. A full remote-broadcast path is separate, +larger work.