Skip to content

Configuration reference

Cang reads a single TOML file at startup. Pass the path via the CLI (see cangcang --help or cangjian --help).

[server]

Key Type Required Default Description
output_dir string (path) yes Root directory for all cang output (snapshots, database).
scan_interval integer no 300 Seconds between periodic re-scans of all camera roots. On NFS mounts, this is the only pickup mechanism; lower the value (e.g. 30) for faster response to new snapshots. Set to 0 to disable.
retention_days integer no 30 How many days to keep motion snapshots before automatic deletion.
background_retention_days integer no 14 How many days to keep background ([F] flag) snapshots before automatic deletion.

Storage layout

Everything cang produces lives under output_dir:

output_dir/
  cang.db                # metadata database
  <camera>/
    snapshots/<YYYY-MM-DD>/<HH.MM.SS>-….jpg        # camera snapshots

Snapshots are moved out of the camera incoming folders on ingest, and emptied date/hour directories are pruned. Anything still present in an incoming folder is unprocessed.

Upgrading from earlier versions

On first startup cang migrates automatically: snapshots referenced by the database move from the incoming folders into the store above. The migration only ever deletes an incoming file after a verified copy exists in output_dir; files not yet processed are untouched. The delete_after_transcode option is gone — a warning is logged if the key is still in your config.

Cleaning up after the video removal (2026.7.23+)

Cang no longer processes or stores video clips. Existing clip files and metadata from earlier versions are not automatically cleaned up. To reclaim disk space:

# Remove all legacy clip files (per-camera)
rm -rf <output_dir>/<camera>/clips/

# Remove the ffmpeg log (if present)
rm -f <output_dir>/ffmpeg.log

# Optionally drop the orphaned clips table
sqlite3 <output_dir>/cang.db "DROP TABLE IF EXISTS clips"

The clips table is harmless if left in place — it uses negligible space and does not affect operation. Only the on-disk files matter for disk usage.

[[camera]]

One [[camera]] block per camera. At least one is expected.

Key Type Required Default Description
name string yes Human-readable label used in logs and the web UI.
adapter string yes Folder-layout adapter. Currently only "dahua" is supported.
root string (path) yes Root directory that the adapter scans for incoming snapshots. For the dahua adapter this must point directly at the camera's serial directory (e.g. /mnt/nvr/ABC123456); date subdirectories are expected immediately inside.

[web]

All keys are optional. Omitting the section uses the defaults shown below.

Key Type Default Description
host string "0.0.0.0" Interface address for the HTTP server.
port integer 8080 TCP port for the HTTP server.
username string Login username. Must be set together with password.
password string Login password. Must be set together with username.

If neither username nor password is set, the web UI is accessible without authentication.

[events]

Optional section controlling how per-camera motion events are chained into cross-camera journeys. All keys are optional; omitting the section uses the defaults shown below.

Key Type Default Description
journey_gap_seconds integer 180 Maximum gap in seconds between the end of one camera's event and the start of another's for both to join into a single journey. Overlap always joins. The window applies per hop, not to total journey duration.

Time synchronisation

Cang prunes empty snapshot source directories once their calendar day has passed. This relies on the server clock agreeing with the cameras' clocks — the server must know when "midnight" is in the same timezone the cameras name their date directories with. If the server and cameras disagree about the current date, pruning may delete directories the camera is still writing to, or leave finished directories unpruned.

All cameras must be in the same timezone as the server, and all clocks must be kept accurate with NTP (Network Time Protocol). Container users should set the TZ environment variable to the camera timezone (e.g. TZ=Australia/Brisbane).

Example

[server]
output_dir = "/var/lib/cang/snapshots"
scan_interval = 300                   # periodic re-scan every 5 minutes (default)
                                      # on NFS mounts, lower this (e.g. 30) for
                                      # faster pickup of new snapshots
retention_days = 30                   # keep motion snapshots for 30 days (default)
background_retention_days = 14        # keep background snapshots for 14 days (default)

[web]
host = "0.0.0.0"
port = 8080
username = "admin"
password = "s3cr3t"

[[camera]]
name = "front-door"
adapter = "dahua"
root = "/mnt/nvr/ABC123456"     # serial directory — date folders sit directly inside

[[camera]]
name = "back-yard"
adapter = "dahua"
root = "/mnt/nvr/DEF789012"