fix(docker): in-container Gemini CLI OAuth, broadcast audio, ports + hardening
Makes the all-in-one image actually run the new real-time-search features and closes review gaps: - Gemini OAuth path: install Node 22 + @google/gemini-cli (pinned 0.46.0) in the image; mount a DEDICATED host dir (~/.config/javis/gemini) holding only the OAuth creds to /root/.gemini (not the whole ~/.gemini). Verified in-container: `gemini -p ... -o json` returns a grounded answer with no API key. - Broadcast audio: add PulseAudio + a headless null-sink (run-pulse.sh, new supervisor program); export XDG_RUNTIME_DIR/PULSE_SERVER so Chrome playback and the selfbot `ffmpeg -f pulse -i @DEFAULT_MONITOR@` share one daemon. Verified: default sink virtual_speaker, monitor present, ffmpeg capture OK. - Bind the brain bridge to 127.0.0.1 only (internal, unauthenticated API). - VNC host port is overridable; this server pins VNC_PORT=5902 (.env) since the host already runs Xvnc on 5901. Verified in-container with CDI GPU passthrough: RTX 5050 visible, NVENC encoders (h264/hevc/av1) available. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -20,9 +20,15 @@ set -euo pipefail
|
||||
: "${PIPER_VOICE_DIR:=/opt/piper-voices}"
|
||||
: "${TTS_PIPER_MODEL_PATH:=${PIPER_VOICE_DIR}/${PIPER_VOICE}.onnx}"
|
||||
|
||||
# Audio: shared PulseAudio socket so Chrome (playback) and the selfbot ffmpeg
|
||||
# (capture of @DEFAULT_MONITOR@) reach the same headless daemon (run-pulse.sh).
|
||||
: "${XDG_RUNTIME_DIR:=/run/user/0}"
|
||||
: "${PULSE_SERVER:=unix:${XDG_RUNTIME_DIR}/pulse/native}"
|
||||
|
||||
export VNC_RESOLUTION OLLAMA_BASE_URL OLLAMA_CHAT_MODEL OLLAMA_EMBED_MODEL \
|
||||
WHISPER_MODEL WHISPER_DEVICE WHISPER_COMPUTE_TYPE JARVIS_DB_PATH \
|
||||
PIPER_VOICE PIPER_VOICE_DIR TTS_PIPER_MODEL_PATH BRIDGE_HOST BRIDGE_PORT
|
||||
PIPER_VOICE PIPER_VOICE_DIR TTS_PIPER_MODEL_PATH BRIDGE_HOST BRIDGE_PORT \
|
||||
XDG_RUNTIME_DIR PULSE_SERVER
|
||||
|
||||
mkdir -p /data /app/config "$(dirname "$JARVIS_DB_PATH")"
|
||||
|
||||
|
||||
23
docker/run-pulse.sh
Executable file
23
docker/run-pulse.sh
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
# Headless PulseAudio for the broadcast audio path.
|
||||
#
|
||||
# The selfbot streamer captures desktop audio with `ffmpeg -f pulse -i
|
||||
# @DEFAULT_MONITOR@` (bot/src/stream/selfbot.ts). In a container there is no
|
||||
# real sound card, so we run a PulseAudio daemon with a null sink set as the
|
||||
# default: Chrome/desktop play into it, and its `.monitor` source is what
|
||||
# ffmpeg captures. Without this the broadcast fails to start when STREAM_AUDIO=1.
|
||||
set -e
|
||||
|
||||
export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/0}"
|
||||
mkdir -p "$XDG_RUNTIME_DIR/pulse"
|
||||
chmod 700 "$XDG_RUNTIME_DIR"
|
||||
|
||||
exec pulseaudio \
|
||||
--exit-idle-time=-1 \
|
||||
--disallow-exit \
|
||||
--disable-shm \
|
||||
-n \
|
||||
--load="module-native-protocol-unix auth-anonymous=1 socket=${XDG_RUNTIME_DIR}/pulse/native" \
|
||||
--load="module-null-sink sink_name=virtual_speaker sink_properties=device.description=Virtual_Speaker" \
|
||||
--load="module-always-sink" \
|
||||
--log-target=stderr
|
||||
@@ -22,6 +22,15 @@ stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
|
||||
[program:pulse]
|
||||
command=/app/docker/run-pulse.sh
|
||||
priority=150
|
||||
autorestart=true
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
|
||||
[program:xfce]
|
||||
command=/app/docker/run-xfce.sh
|
||||
priority=200
|
||||
|
||||
Reference in New Issue
Block a user