Run With Docker Compose#

This guide covers building the images from source and running the full stack with docker compose. For source code changes to any service, see Build from Source.

Microphone audio is captured by the browser and uploaded to kiosk-core as a WAV file. No host audio device is passed into the containers.

Prerequisites#

  1. Complete Steps 1–4 of Get Started (Docker, GPU drivers, repo clone, HuggingFace token).

  2. Run ./setup_models.sh to download the OVMS LLM model (Step 5 of Get Started). The stack will not start correctly without it.

Build and Start#

From smart-kiosk-assistant/:

make check-env
make up

For OpenVINO + NPU (models.asr.provider=openvino, models.asr.device=NPU), this is the recommended path because the Makefile:

  • detects the host NPU node under /dev/accel/accel*

  • validates that OpenVINO can see NPU inside the audio-analyzer container

  • passes the detected host node through ACCEL_MOUNT_PATH

Direct Compose behavior is different: it does not run Makefile detection. If you intentionally run Compose directly with OpenVINO + NPU, set ACCEL_MOUNT_PATH yourself:

ACCEL_MOUNT_PATH=/dev/accel/accel0 docker compose up -d audio-analyzer

ACCEL_MOUNT_PATH is the host NPU device node. The value above is a common example; actual host path may vary. Compose maps it into the container at /dev/accel/accel0.

Container

Port

Purpose

ovms-llm

8000

Serves Qwen3-4B via OpenAI-compatible API

metrics-collector

9000

Hardware utilization metrics

audio-analyzer

8010

Whisper ASR + speaker diarization

text-to-speech

8011

SpeechT5 TTS synthesis

rag-service

8020

RAG pipeline + ordering agent

kiosk-core

8012

Session API + product ordering

kiosk-ui

7860

React kiosk UI — operator screen (chat, performance dashboard)

kiosk-ui-customer

7861

React kiosk UI — customer screen (queue-aware menu, cart, voice Ask)

Both kiosk-ui and kiosk-ui-customer are the exact same image/build; only the KIOSK_UI_MODE environment variable and published port differ (see Configuration). There is no separate Dockerfile or build context for the customer screen.

Containers run as non-root; every image is built with UID/GID 1000:1000 and the named volumes are initialized with that ownership, so no host UID/GID configuration is required.

Verify#

docker compose ps
curl --noproxy '*' http://127.0.0.1:8000/v3/models   # ovms-llm
curl --noproxy '*' http://127.0.0.1:8010/health       # audio-analyzer
curl --noproxy '*' http://127.0.0.1:8011/health       # text-to-speech
curl --noproxy '*' http://127.0.0.1:8020/health       # rag-service
curl --noproxy '*' http://127.0.0.1:8012/health       # kiosk-core

Open http://127.0.0.1:7860 for the operator screen (chat + performance dashboard) — click the microphone and speak your question.

Open http://127.0.0.1:7861 for the customer kiosk screen — a single view with the queue-aware menu, live cart, and a full-width Ask button. Intended for the physical kiosk touchscreen (tested at 1920×1080 landscape) while the operator screen runs on a separate monitor.

Logs#

docker compose logs -f kiosk-core
docker compose logs -f kiosk-ui
docker compose logs -f kiosk-ui-customer

Restart / Stop#

docker compose restart            # after env var change
docker compose build && docker compose up -d   # after a source code change
docker compose down               # teardown

Notes#

  • The default Compose wiring connects kiosk-core and kiosk-ui to the internal audio-analyzer, rag-service, and text-to-speech containers. Override these URLs only when this stack must call services outside the local Compose network.

  • See Configuration for environment variables, model selection, and inference device, and API Reference for endpoint details.