Files
meetrec/server/whisper-server/docker-compose.yml
T
fegger ef59fc0fb4 Add dockerized whisper.cpp inference server (Vulkan GPU, Tailscale)
- server/whisper-server: compose stack built from the pinned whisper.cpp
  v1.9.3 release, same as the Android JNI layer
- Vulkan GPU backend (AMD Radeon AI PRO R9700 / RADV) with transparent
  CPU fallback and NO_GPU override; GGML models auto-download on first
  start (MODEL env, default large-v3)
- API bound to the Tailscale interface only (100.103.83.12:8080) since
  whisper-server has no authentication; render-group GID passthrough for
  /dev/dri
- validated locally: image builds, entrypoint downloads tiny, POST
  /inference returns verbose_json with language + segments; GPU-less
  fallback confirmed
2026-09-07 12:17:40 +02:00

48 lines
1.7 KiB
YAML

# whisper.cpp inference server for meetrec, with Vulkan GPU support
# (AMD Radeon AI PRO R9700), reachable over Tailscale.
#
# RENDER_GID=$(getent group render | cut -d: -f3) docker compose up -d --build
#
# Security: whisper.cpp's server has NO authentication. The port below is
# bound ONLY to the Tailscale interface (100.103.83.12), so the API is
# never exposed to the LAN or the internet. Tailscale must own that IP
# before the container starts, otherwise the bind fails — start order:
# tailscale first, then `docker compose up -d`. If you would rather
# tolerate LAN exposure, use "8080:8080" instead.
services:
whisper-server:
build: .
image: meetrec-whisper-server:latest
container_name: whisper-server
restart: unless-stopped
environment:
# tiny | base | small | medium | large-v3 (downloads on first start)
MODEL: large-v3
THREADS: 8
HOST: 0.0.0.0 # inside the container; the host bind is below
PORT: 8080
# NO_GPU: 1 # force CPU if the GPU ever misbehaves
volumes:
- ./models:/models # keep downloads across container rebuilds
ports:
- "100.103.83.12:8080:8080" # tailscale-only; see note above
# GPU passthrough: the render group must match the host's GID, hence
# the RENDER_GID env var in the comment at the top of this file.
devices:
- /dev/dri:/dev/dri
group_add:
- video
- "${RENDER_GID:-110}"
healthcheck:
# any HTTP response counts as healthy (the server has no /health)
test: ["CMD-SHELL", "curl -s -o /dev/null http://localhost:8080/ || exit 1"]
interval: 30s
timeout: 5s
retries: 3
start_period: 60s