Docker
Docker is the recommended way to run the camera.ui server on Linux. The image is built on Ubuntu 24.04 and stays small: on first start it downloads and installs the server itself, so updates don't need a new image. There is one image per hardware target, published as ghcr.io/cameraui/camera.ui.
Before you start
You need a Linux host with Docker Engine and the Compose plugin.
Docker Desktop won't work
Docker Desktop on macOS and Windows can't use host networking, which camera.ui relies on for mDNS and WebRTC. On those platforms, use the desktop app instead.
Quick start
Save this as docker-compose.yml:
name: cameraui
services:
cameraui:
image: ghcr.io/cameraui/camera.ui:latest
container_name: cameraui
restart: unless-stopped
network_mode: host
environment:
- TZ=Europe/Berlin
- CAMERAUI_DOCKER_AVAHI=true
volumes:
- cameraui-data:/data
volumes:
cameraui-data:Start it:
docker compose up -dThen open https://<host>:3443. The first boot downloads and installs the server, which takes a few minutes. Follow along with docker compose logs -f.
Your browser shows a self-signed certificate warning on first visit, and the app then walks you through first-run setup. See Getting started for what comes next.
First boot needs internet
On first start the container downloads the server from the npm registry. If your host can't resolve it, add public DNS resolvers (1.1.1.1, 8.8.8.8) to the service.
Hardware acceleration
The default image (latest) runs detection and video processing in software. For better performance, pick the flavor that matches your hardware and layer its override on top of the base file.
| Flavor | Tag | Hardware acceleration | Arch |
|---|---|---|---|
| CPU | latest | software | amd64 + arm64 |
| Intel | intel | Quick Sync / VA-API + OpenCL | amd64 |
| NVIDIA | nvidia | NVENC / NVDEC + CUDA | amd64 |
| AMD | amd | Mesa VA-API + OpenCL | amd64 |
Save the matching override next to your docker-compose.yml:
name: cameraui
services:
cameraui:
image: ghcr.io/cameraui/camera.ui:intel
devices:
- /dev/dri:/dev/driname: cameraui
services:
cameraui:
image: ghcr.io/cameraui/camera.ui:nvidia
environment:
- NVIDIA_VISIBLE_DEVICES=all
- NVIDIA_DRIVER_CAPABILITIES=all
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu, compute, video, utility]name: cameraui
services:
cameraui:
image: ghcr.io/cameraui/camera.ui:amd
devices:
- /dev/dri:/dev/driThen start both files together (Intel shown here):
docker compose -f docker-compose.yml -f docker-compose.intel.yml up -dThe NVIDIA flavor also requires the NVIDIA Container Toolkit on the host. Ready-made compose files for every flavor are in the cameraui/docker repository.
Host drivers, device passthrough for AI accelerators (Coral, Hailo, Intel NPU) and how to verify it all works are covered on the Hardware acceleration page.
Networking
Host networking (the compose default) is recommended. camera.ui uses it for mDNS / Bonjour (HomeKit pairing, ONVIF discovery) and for WebRTC live view. If you can't use host networking, publish the ports below explicitly instead.
Storage for recordings
By default, recordings live in the /data volume alongside everything else. To keep them on a separate, dedicated disk, bind-mount it and point the NVR at it:
volumes:
- cameraui-data:/data
- /mnt/recordings:/recordings
environment:
- CAMERAUI_PLUGIN_NVR_STORAGE_PATH=/recordingsUse a dedicated local disk for /recordings, not a network share. See System requirements.
Workers
A worker is a second machine that takes over camera work (decoding, detection, plugins) from your main server. It runs no UI and no streaming engine of its own. It uses the same image as the server, started in worker mode with CAMERA_UI_WORKER=true.
Enable workers on the main server first and generate a pairing code there. The compose file for the worker machine, the environment variables it takes, and how to assign cameras to it are on Workers.
CAMERA_UI_WORKER_CAPABILITIES narrows what the worker takes on: frameDecoding for decoding and detection, pluginHost for running plugins. Leave it unset and the worker offers both.
Ports
camera.ui uses these ports (already covered by host networking):
| Port | Proto | Purpose |
|---|---|---|
| 3443 | tcp | HTTPS UI / API |
| 2000 | tcp | go2rtc |
| 2001 | tcp | RTSP |
| 2002 | tcp | SRTP |
| 2003 | tcp | RTMP |
| 2004 | tcp | WebRTC |
| 1883 | tcp | MQTT broker, only if you enable the built-in one |
WebRTC also uses UDP on ports picked per connection. Without host networking, live view falls back to TCP on 2004.
Data & backups
All state lives in the cameraui-data volume: config, database, recordings, and TLS certificates. Back up that volume to keep a copy. See Backup & restore.
Updating
Pulling a new image does not update the server, only the image (OS, GPU libraries, and launcher): the launcher keeps the server version installed in the cameraui-data volume. Update the server from the Updates page, or run cameraui update-server -H /data in the container, then restart it. To update the image, pull and recreate the container:
docker compose pull
docker compose up -dSee Updating for details.