Link the published Docker Hub repo (https://hub.docker.com/r/palashdeb/ omnivoice-studio) as an official image alongside GHCR in the README install list and docker.md header. Same images, same tags. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
147 lines
6.7 KiB
Markdown
147 lines
6.7 KiB
Markdown
# OmniVoice Studio — Install with Docker
|
|
|
|
For headless servers, dedicated GPUs, or "I want one command" deployments.
|
|
The docker image bundles the backend; the UI is served over HTTP and you open
|
|
it in a normal browser.
|
|
|
|
**Official images:** [`ghcr.io/debpalash/omnivoice-studio`](https://github.com/debpalash/OmniVoice-Studio/pkgs/container/omnivoice-studio)
|
|
and [`palashdeb/omnivoice-studio` on Docker Hub](https://hub.docker.com/r/palashdeb/omnivoice-studio) — same images, same tags.
|
|
|
|
> **Image ↔ version mapping**
|
|
>
|
|
> | Tag | What you get |
|
|
> |-----|--------------|
|
|
> | `:latest` | **Rolling preview** — latest commit on `main` (always one patch ahead of the last release). This is the preview channel; pin `:stable` for production. |
|
|
> | `:stable` | Most recent versioned release (updated on every `v*` git tag) |
|
|
> | `:0.3.6` | Exact release version |
|
|
> | `:0.3` | Latest patch within the 0.3 minor |
|
|
> | `:main` | Alias of the same rolling `main` build as `:latest` |
|
|
> | `:sha-xxxxxxx` | Specific commit (produced by manual workflow dispatch) |
|
|
>
|
|
> Versioning rule: `main` always carries *last release + 1 patch*, so `:latest`
|
|
> (preview) version-sorts above `:stable` — upgrades flow naturally.
|
|
>
|
|
> **Note on the update-channel toggle:** The update-channel UI (Settings → About → Update channel) is part of the Tauri desktop app's built-in auto-updater. It does **not** apply to the Docker image — the Docker image is the headless web-server build. To update your Docker deployment, pull the new image tag and recreate the container (`docker compose pull && docker compose up -d`).
|
|
|
|
## Pull and run (CPU)
|
|
|
|
```bash
|
|
docker pull ghcr.io/debpalash/omnivoice-studio:latest
|
|
|
|
docker run -d --name omnivoice \
|
|
-p 127.0.0.1:3900:3900 \
|
|
-v omnivoice-data:/app/omnivoice_data \
|
|
-v ~/.cache/huggingface:/root/.cache/huggingface \
|
|
ghcr.io/debpalash/omnivoice-studio:latest
|
|
```
|
|
|
|
> **Docker Hub mirror:** the same images are published to
|
|
> `palashdeb/omnivoice-studio` on Docker Hub with identical tags — swap the
|
|
> image for `palashdeb/omnivoice-studio:latest` if you prefer Docker Hub.
|
|
> Tag semantics (`:latest` = rolling main preview, `:stable`/`:X.Y.Z` =
|
|
> releases) are the same on both registries.
|
|
|
|
Open [http://localhost:3900](http://localhost:3900). The first run downloads
|
|
~2.4 GB of model weights — follow `docker logs -f omnivoice` to watch.
|
|
|
|
## Pull and run (NVIDIA GPU)
|
|
|
|
```bash
|
|
docker run -d --name omnivoice --gpus all \
|
|
-p 127.0.0.1:3900:3900 \
|
|
-v omnivoice-data:/app/omnivoice_data \
|
|
-v ~/.cache/huggingface:/root/.cache/huggingface \
|
|
ghcr.io/debpalash/omnivoice-studio:latest
|
|
```
|
|
|
|
GPU mode requires the
|
|
[NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html)
|
|
on the host.
|
|
|
|
## Docker Compose (recommended)
|
|
|
|
```bash
|
|
# CPU
|
|
docker compose -f deploy/docker-compose.yml --profile cpu up -d
|
|
|
|
# NVIDIA GPU
|
|
docker compose -f deploy/docker-compose.yml --profile gpu up -d
|
|
```
|
|
|
|
The `docker-compose.yml` shipped in `deploy/` defaults to `127.0.0.1:3900`
|
|
on the host. The backend inside the container binds to `0.0.0.0` so the
|
|
host port mapping can forward — the host-side `127.0.0.1` binding is what
|
|
enforces loopback-only.
|
|
|
|
## LAN access
|
|
|
|
<a id="lan-access"></a>
|
|
|
|
To expose OmniVoice on your LAN (e.g. you're running it on a homelab box and
|
|
opening the UI from a laptop), change the host port mapping:
|
|
|
|
```yaml
|
|
# deploy/docker-compose.yml
|
|
services:
|
|
omnivoice:
|
|
ports:
|
|
- "0.0.0.0:3900:3900" # ← was 127.0.0.1:3900:3900
|
|
```
|
|
|
|
The OmniVoice frontend defaults to the **same origin** the page was served
|
|
from, so opening the UI from `http://<lan-ip>:3900` Just Works for both the
|
|
page load *and* the API/media requests it makes afterwards.
|
|
|
|
If you front the app with a **reverse proxy** and the API and UI land on
|
|
different origins, pin the API base explicitly. Use **`OMNIVOICE_PUBLIC_API_BASE`**
|
|
— a *runtime* env var the backend injects into the page, so it works with the
|
|
prebuilt image via `docker run -e` (the older `VITE_OMNIVOICE_API` is inlined at
|
|
*build* time and cannot be set on a prebuilt image):
|
|
|
|
```bash
|
|
docker run -e OMNIVOICE_PUBLIC_API_BASE=https://api.your-host.example \
|
|
-p 0.0.0.0:3900:3900 \
|
|
ghcr.io/debpalash/omnivoice-studio:latest
|
|
```
|
|
|
|
> `OMNIVOICE_PUBLIC_API_BASE` must be a plain `http(s)://…` URL; anything else
|
|
> is ignored and the app falls back to same-origin. If you build from source you
|
|
> may instead bake `VITE_OMNIVOICE_API` at build time, but the runtime var above
|
|
> is simpler and image-agnostic.
|
|
|
|
> **Security:** OmniVoice ships no authentication. Anything on your LAN with
|
|
> the URL can use the app. Put it behind a reverse proxy with `basic_auth`
|
|
> (Caddy / nginx + htpasswd) or a private network overlay (Tailscale, ZeroTier)
|
|
> before exposing publicly.
|
|
|
|
## Volume mounts
|
|
|
|
Two paths are worth persisting across container restarts:
|
|
|
|
| Mount | Purpose | Why |
|
|
|-------|---------|-----|
|
|
| `omnivoice_data:/app/omnivoice_data` | Project DB, user voices, settings | Survives upgrade; encrypted HF token lives here |
|
|
| `~/.cache/huggingface:/root/.cache/huggingface` | HF model cache | Re-using your host's cache saves ~2.4 GB of re-downloads |
|
|
|
|
## Troubleshooting
|
|
|
|
- **Container reports 0.2.7 but image is tagged 0.3.x:** This was a workflow bug
|
|
(fixes #249, #251) — the `:latest` tag was not being updated on release tag
|
|
pushes. Pull the image again after the fix is merged: `docker pull ghcr.io/debpalash/omnivoice-studio:latest`.
|
|
The running version is now shown in **Settings → About → Version** (read live
|
|
from the backend), so the web UI no longer displays a dash in Docker.
|
|
- **Checking which version is running:** `docker exec omnivoice python -c "import importlib.metadata; print(importlib.metadata.version('omnivoice'))"`, or hit the `/health` endpoint — it returns `{"status": "ok", "device": ..., "version": "0.3.x"}`.
|
|
- **"Loopback origin required" errors (and a blank version):** the desktop
|
|
build restricts the `/system/*` and `/api/settings/*` routes to a loopback
|
|
origin, but Docker's NAT makes every request look non-loopback, so the gate
|
|
used to 403 the whole admin UI (issue #261). The image now ships with
|
|
`OMNIVOICE_SERVER_MODE=1`, which relaxes that gate for the headless
|
|
deployment — exposure is instead governed by your `-p` port mapping (keep the
|
|
`127.0.0.1:` prefix to stay local) plus the optional share PIN. If you front
|
|
the container with your own auth proxy on loopback, set `OMNIVOICE_SERVER_MODE=0`
|
|
to re-enable the strict gate.
|
|
- **Media-preview 404 in LAN mode:** see the [LAN access](#lan-access) section
|
|
above — the `window.location.host` fix shipped in v0.3.
|
|
- **GPU not detected:** verify `docker run --rm --gpus all nvidia/cuda:12.8.0-base-ubuntu22.04 nvidia-smi` succeeds first.
|
|
- More entries: [docs/install/troubleshooting.md](troubleshooting.md).
|