Some checks failed
Release / semantic-release (push) Successful in 31s
Release / build-windows (push) Has been cancelled
Release / build-macos (arm64, macos-latest) (push) Has been cancelled
Release / build-macos (x64, macos-15-intel) (push) Has been cancelled
Release / build-linux (push) Has been cancelled
Release / release-main (push) Has been cancelled
Release / release-develop (push) Has been cancelled
tests / Unit tests (Linux, Python 3.11) (push) Has been cancelled
The user chose Microsoft Edge TTS, voice ko-KR-HyunsuMultilingualNeural at rate +45% (~1.45x), as the natural Korean voice. Wire it into the bridge and make it the default engine. - bridge/server.py: _edge_synthesize() calls edge-tts and transcodes the MP3 to PCM16 mono WAV with the system ffmpeg (temp file for a correct header); TTS_ENGINE default -> edge; EDGE_TTS_VOICE / EDGE_TTS_RATE env-driven - requirements-bridge.txt: add edge-tts (lightweight; httpx) - compose/.env.example/README: TTS_ENGINE=edge + EDGE_TTS_* knobs; note the online/privacy trade-off (reply text is sent to Microsoft, needs internet) - drop the now-unused MeloTTS build layer (Dockerfile) and melo-worker (supervisord) — edge synthesises in-process, no model/worker baked, slimmer and faster image; settings UI engine list -> edge/piper, restart only bridge Verified on host: edge-tts -> ffmpeg yields a valid 16-bit mono 24kHz WAV; envsubst renders tts_engine=edge; docker build --check + 26 tests pass. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
99 lines
4.6 KiB
Docker
99 lines
4.6 KiB
Docker
# ============================================================================
|
|
# Javis Bot — all-in-one container
|
|
# VNC + XFCE desktop + Chrome + Python brain bridge + Node/bun Discord bot.
|
|
# Ollama (the LLM backend) runs as a separate service (see docker-compose.yml).
|
|
# ============================================================================
|
|
FROM ubuntu:24.04
|
|
|
|
ENV DEBIAN_FRONTEND=noninteractive \
|
|
LANG=C.UTF-8 \
|
|
DISPLAY=:1 \
|
|
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 \
|
|
PATH=/opt/venv/bin:/root/.bun/bin:/usr/local/bin:/usr/bin:/bin \
|
|
NVIDIA_VISIBLE_DEVICES=all
|
|
|
|
# `video` is REQUIRED for NVENC/NVDEC: it tells the NVIDIA Container Toolkit to
|
|
# inject libnvidia-encode.so.1 / libnvidia-decode.so.1 into the container. With
|
|
# only `compute,utility` you get CUDA (ollama/whisper/melo) + nvidia-smi, but the
|
|
# Go-Live broadcast's h264_nvenc fails with "Cannot load libnvidia-encode.so.1".
|
|
# Applies on both Linux (CDI) and Windows Docker Desktop (WSL2).
|
|
ENV NVIDIA_DRIVER_CAPABILITIES=compute,utility,video
|
|
|
|
# --- System packages: desktop, VNC, Chrome deps, ffmpeg, python, ocr ---
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
ca-certificates curl wget gnupg unzip procps \
|
|
tigervnc-standalone-server tigervnc-common tigervnc-tools \
|
|
xfce4 xfce4-goodies dbus-x11 x11-utils xfonts-base \
|
|
fonts-noto-cjk fonts-noto-cjk-extra fonts-nanum \
|
|
ffmpeg tesseract-ocr \
|
|
pulseaudio pulseaudio-utils \
|
|
python3 python3-venv python3-pip \
|
|
novnc websockify supervisor gettext-base \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# --- Google Chrome (stable) ---
|
|
RUN wget -q -O /tmp/chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb \
|
|
&& (apt-get update && apt-get install -y --no-install-recommends /tmp/chrome.deb || (apt-get -f install -y)) \
|
|
&& rm -f /tmp/chrome.deb && rm -rf /var/lib/apt/lists/*
|
|
|
|
# --- bun (Discord bot runtime/package manager) ---
|
|
RUN curl -fsSL https://bun.sh/install | bash
|
|
|
|
# --- Node.js + Gemini CLI (the GEMINI_AUTH=oauth real-time search path shells
|
|
# out to `gemini`; it needs a real Node runtime, not bun). The account
|
|
# login itself is provided at runtime via the mounted ~/.gemini (see
|
|
# docker-compose.yml); here we only install the binary. ---
|
|
ARG GEMINI_CLI_VERSION=0.46.0
|
|
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
|
|
&& apt-get install -y --no-install-recommends nodejs \
|
|
&& npm install -g "@google/gemini-cli@${GEMINI_CLI_VERSION}" \
|
|
&& rm -rf /var/lib/apt/lists/* \
|
|
&& gemini --version
|
|
|
|
# --- Python brain/bridge deps (slim set) ---
|
|
COPY bridge/requirements-bridge.txt /app/bridge/requirements-bridge.txt
|
|
RUN python3 -m venv /opt/venv \
|
|
&& /opt/venv/bin/pip install --no-cache-dir --upgrade pip \
|
|
&& /opt/venv/bin/pip install --no-cache-dir -r /app/bridge/requirements-bridge.txt
|
|
|
|
# faster-whisper>=1.1 / ctranslate2 self-locates these pip CUDA libs at runtime,
|
|
# so no hardcoded LD_LIBRARY_PATH is needed. We also register them with the
|
|
# dynamic linker (full path to ldconfig; PATH excludes /sbin) as a robust
|
|
# fallback. Path-glob is python-version agnostic.
|
|
RUN ls -d /opt/venv/lib/python*/site-packages/nvidia/cublas/lib \
|
|
/opt/venv/lib/python*/site-packages/nvidia/cudnn/lib \
|
|
> /etc/ld.so.conf.d/nvidia-cu12.conf 2>/dev/null \
|
|
&& /sbin/ldconfig || true
|
|
|
|
# --- Korean voice: Microsoft Edge TTS (online neural). No model is baked — the
|
|
# `edge-tts` pip package (in requirements-bridge.txt) calls the MS service at
|
|
# runtime and the bridge transcodes the MP3 to PCM16 with ffmpeg. No heavy
|
|
# TTS build layer is needed. ---
|
|
|
|
# --- Human input + window management for the on-screen Chrome control tool.
|
|
# xdotool injects real X pointer/keyboard events (visible cursor,
|
|
# char-by-char typing) into the broadcast; wmctrl lists/moves windows. ---
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
xdotool wmctrl \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# --- Discord bot deps (cache layer on lockfile) ---
|
|
COPY bot/package.json bot/bun.lock /app/bot/
|
|
RUN cd /app/bot && bun install --frozen-lockfile || bun install
|
|
|
|
# --- App source ---
|
|
COPY . /app
|
|
WORKDIR /app
|
|
|
|
# Normalise all container shell scripts to LF. On a Windows checkout (autocrlf)
|
|
# these arrive as CRLF, which would break their shebangs at runtime (entrypoint,
|
|
# run-*.sh) the same way it broke setup-melo.sh at build time.
|
|
RUN find /app/docker /app/scripts -name '*.sh' -exec sed -i 's/\r$//' {} +
|
|
|
|
# --- Default Piper voice (best-effort at build; entrypoint retries if absent) ---
|
|
RUN bash docker/download-piper.sh || true
|
|
|
|
EXPOSE 5901 6080 8765
|
|
|
|
ENTRYPOINT ["/app/docker/entrypoint.sh"]
|