Skip to content

Running cang in a container

Cang is published as an OCI image to two registries and can be run with Podman, Docker, or any OCI-compatible runtime.

codeberg.org/minimalnvr/cang:latest   # Codeberg (primary)
marvin8/cang:latest                    # Docker Hub

Both images are identical. Use whichever registry suits your setup.

Quick start with Docker Compose

Create a minimal cang.toml (see configuration reference):

[server]
output_dir = "/data"

[[camera]]
name = "front-door"
adapter = "dahua"
root = "/mnt/nvr/ABC123456"

Then run:

podman compose up -d
# or: docker compose up -d

The web UI will be available at http://localhost:8080/days.

Bind-mount layout

Container path What to mount Mode
/config/cang.toml Your cang.toml config file :ro
/data Output directory for transcoded clips and cang.db read-write
<camera root> Each camera[].root path from cang.toml, at the same path :ro

Camera roots must be mounted at the same path inside the container as declared in cang.toml. For example, if your config contains root = "/mnt/nvr/ABC123456", mount /mnt/nvr/ABC123456 into the container at /mnt/nvr/ABC123456.

Full compose.yaml example

services:
  cang:
    image: codeberg.org/minimalnvr/cang:latest
    ports:
      - "8080:8080"
    volumes:
      - ./cang.toml:/config/cang.toml:ro
      - cang-data:/data
      # one entry per camera root declared in cang.toml:
      - /mnt/nvr/ABC123456:/mnt/nvr/ABC123456:ro
    restart: unless-stopped

volumes:
  cang-data:

Building locally

podman build -t cang .
podman run --rm \
  -v ./cang.toml:/config/cang.toml:ro \
  -v /tmp/cang-data:/data \
  -v /mnt/nvr/ABC123456:/mnt/nvr/ABC123456:ro \
  -p 8080:8080 \
  cang

Systemd Quadlet setup

Quadlet is the recommended way to run Podman containers as persistent systemd services without root.

Create ~/.config/containers/systemd/cang.container:

[Unit]
Description=Cang NVR
Wants=network-online.target
After=network-online.target

[Container]
Image=codeberg.org/minimalnvr/cang:latest
PublishPort=8080:8080
Volume=%h/.config/cang/cang.toml:/config/cang.toml:ro,z
Volume=%h/.local/share/cang:/data:z
# repeat for each camera root declared in cang.toml:
Volume=/mnt/nvr/ABC123456:/mnt/nvr/ABC123456:ro,z

[Service]
Restart=on-failure

[Install]
WantedBy=default.target

%h expands to your home directory. Place cang.toml at ~/.config/cang/cang.toml, then activate:

systemctl --user daemon-reload
systemctl --user enable --now cang

To start automatically at boot without a logged-in session:

loginctl enable-linger

The ,z SELinux relabel suffix on volume mounts is required on SELinux-enforcing systems (Fedora, RHEL, etc.); omit it on systems without SELinux.