Skip to content

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:

yaml
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:

bash
docker compose up -d

Then 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.

FlavorTagHardware accelerationArch
CPUlatestsoftwareamd64 + arm64
IntelintelQuick Sync / VA-API + OpenCLamd64
NVIDIAnvidiaNVENC / NVDEC + CUDAamd64
AMDamdMesa VA-API + OpenCLamd64

Save the matching override next to your docker-compose.yml:

yaml
name: cameraui
services:
  cameraui:
    image: ghcr.io/cameraui/camera.ui:intel
    devices:
      - /dev/dri:/dev/dri
yaml
name: 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]
yaml
name: cameraui
services:
  cameraui:
    image: ghcr.io/cameraui/camera.ui:amd
    devices:
      - /dev/dri:/dev/dri

Then start both files together (Intel shown here):

bash
docker compose -f docker-compose.yml -f docker-compose.intel.yml up -d

The 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:

yaml
    volumes:
      - cameraui-data:/data
      - /mnt/recordings:/recordings
    environment:
      - CAMERAUI_PLUGIN_NVR_STORAGE_PATH=/recordings

Use 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):

PortProtoPurpose
3443tcpHTTPS UI / API
2000tcpgo2rtc
2001tcpRTSP
2002tcpSRTP
2003tcpRTMP
2004tcpWebRTC
1883tcpMQTT 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:

bash
docker compose pull
docker compose up -d

See Updating for details.