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#
Complete Steps 1–4 of Get Started (Docker, GPU drivers, repo clone, HuggingFace token).
Run
./setup_models.shto 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
NPUinside theaudio-analyzercontainerpasses 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 |
|---|---|---|
|
8000 |
Serves Qwen3-4B via OpenAI-compatible API |
|
9000 |
Hardware utilization metrics |
|
8010 |
Whisper ASR + speaker diarization |
|
8011 |
SpeechT5 TTS synthesis |
|
8020 |
RAG pipeline + ordering agent |
|
8012 |
Session API + product ordering |
|
7860 |
React kiosk UI — operator screen (chat, performance dashboard) |
|
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-coreandkiosk-uito the internalaudio-analyzer,rag-service, andtext-to-speechcontainers. 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.