Install (Docker Compose)
ChannelWatch ships as a multi-arch Docker image and is designed to run as a single container managed by Docker Compose. This is the primary supported install path today.
Prerequisites
Section titled “Prerequisites”- Docker Engine with Docker Compose v2 (the
docker composeplugin, not the legacydocker-composebinary) - A running Channels DVR server reachable from the Docker host
- A local directory to store ChannelWatch configuration and logs (e.g.
/opt/channelwatch/config)
Supported architectures
Section titled “Supported architectures”The coderluii/channelwatch:latest image is a multi-platform manifest that automatically selects the right variant for your hardware:
| Architecture | Typical hardware |
|---|---|
linux/amd64 |
Standard x86-64 servers, NAS devices, PCs |
linux/arm64 |
Raspberry Pi 4/5, Apple Silicon Docker hosts, modern ARM servers |
No flags or extra steps are needed. docker compose pull picks the correct image automatically.
Compose file
Section titled “Compose file”Create a docker-compose.yml in a directory of your choice:
name: channelwatchservices: channelwatch: image: coderluii/channelwatch:latest container_name: channelwatch init: true network_mode: host volumes: - /your/local/path:/config environment: TZ: "America/New_York" restart: unless-stoppedReplace /your/local/path with the absolute path to your config directory. The TZ value should match your local timezone (IANA format, e.g. America/Chicago, Europe/London).
Start the container
Section titled “Start the container”docker compose up -dThen open http://your-server-ip:8501 in a browser. On a fresh install, ChannelWatch opens its first-run setup flow so you can add your Channels DVR server in the web UI.

The container exposes port 8501 and the published image defines a built-in liveness check against http://127.0.0.1:8501/healthz/live.
View logs
Section titled “View logs”docker logs -f channelwatchHost vs bridge networking
Section titled “Host vs bridge networking”The default compose file uses network_mode: host, which lets ChannelWatch reach your Channels DVR server using localhost or any LAN IP without extra configuration. This is the simplest option for most home lab setups.
This host-network example targets Linux Docker Engine. For Docker Desktop or a host where host networking is unavailable, use the bridge configuration below and enter the DVR’s reachable LAN address.
If you prefer bridge networking, for network isolation or port remapping, replace the network_mode line with explicit port mapping:
# Remove: network_mode: host ports: - "8501:8501"Volume mounts
Section titled “Volume mounts”ChannelWatch stores all persistent data under /config inside the container. The directory you mount there will contain:
| Path | Contents |
|---|---|
/config/settings.json |
All configuration (DVR servers, alert toggles, notification providers) |
/config/channelwatch.db |
SQLite activity history database |
/config/encryption.key |
Managed key used to encrypt DVR API keys and custom webhook credentials |
/config/logs/ |
Application logs |
/config/backups/ |
Automatic pre-migration backups |
/config/plugins/notifications/ |
Optional notification provider plugins |
Optional environment variables
Section titled “Optional environment variables”Most settings live in the web UI. A small set of environment variables are available for automation or headless deployments:
environment: TZ: "America/New_York"
# User/group IDs (match your host user to avoid permission issues) # PUID: "1000" # PGID: "1000"
# Log verbosity: 0=minimal, 1=standard (default), 2=verbose # CW_LOG_LEVEL: "1"
# Notification providers (can also be set in the web UI) # CW_APPRISE_DISCORD: "<webhook-id>/<webhook-token>" # CW_APPRISE_PUSHOVER: "<pushover-user-key>@<pushover-api-token>" # CW_APPRISE_TELEGRAM: "<bot-token>/<chat-id>" # CW_APPRISE_SLACK: "<token-a>/<token-b>/<token-c>" # CW_APPRISE_GOTIFY: "<gotify-host>/<gotify-app-token>" # CW_APPRISE_EMAIL: "<smtp-user>:<smtp-password>@smtp.example.com" # CW_APPRISE_EMAIL_TO: "recipient@example.com" # CW_APPRISE_MATRIX: "<matrix-user>:<matrix-password>@matrix.example.com/#room" # CW_APPRISE_CUSTOM: "apprise://<service-specific-url>"
# First-start alert overrides (fresh defaults use Important Only) # CW_ALERT_CHANNEL_WATCHING: "true" # CW_ALERT_VOD_WATCHING: "true" # CW_ALERT_DISK_SPACE: "true" # CW_ALERT_RECORDING_EVENTS: "true"
# Disk space thresholds # CW_DS_THRESHOLD_PERCENT: "10" # CW_DS_THRESHOLD_GB: "50" # CW_DS_ALERT_COOLDOWN: "3600"PUID and PGID are most useful on NAS and appliance-style hosts such as Synology, Unraid, and TrueNAS SCALE, where the Docker daemon often writes mounted files as a non-login service user by default. Set both values to the UID and GID that should own the /config directory on the host if you see permission errors or root-owned files after first start.
Provider, alert, threshold, and log-level variables seed a fresh settings file. After setup, manage those values in the UI; changing them in Compose does not replace existing saved settings. TZ remains a startup override. For DVR variables and their separate runtime behavior, read Environment Bootstrap Config.
DNS configuration
Section titled “DNS configuration”If your Channels DVR server is reachable by a short hostname, for example media-server instead of a full IP, you can configure DNS search domains:
dns_search: localdomain # Tailscale users: add your Tailnet domain # dns_search: # - localdomain # - tail12345.ts.netFor public names, you can configure reachable DNS servers explicitly:
dns: - 1.1.1.1 - 8.8.8.8Public resolvers cannot answer private LAN or Tailnet names. Use your local resolver when the DVR has a private hostname, and confirm the container can reach it.
Upgrading
Section titled “Upgrading”ChannelWatch v1.6.5 installs from Settings > Updates on v1.4.0, v1.4.1, v1.4.5, v1.5.3, v1.6.0, v1.6.1, v1.6.2, v1.6.3, and v1.6.4 without recreating the container. The v1.4.x and protocol 3 v1.6.0/v1.6.1/v1.6.2/v1.6.3/v1.6.4 paths keep the existing image’s Python packages and system libraries; v1.5.3 and protocol 4 v1.6.0/v1.6.1/v1.6.2/v1.6.3/v1.6.4 install the complete signed runtime generation. To refresh the container image separately, keep the same /config mount and run:
docker compose pulldocker compose up -dChannelWatch migrates /config/settings.json automatically on startup. A timestamped backup is written to /config/backups/ before any migration step runs. Keep /config/encryption.key with the rest of /config; losing it prevents ChannelWatch from decrypting protected credentials. See Migrating from v0.7 for version-pinning, rollback, and downgrade caveats.
Security hardening (optional)
Section titled “Security hardening (optional)”To prevent supervisor credentials from ever touching disk, mount /run/channelwatch as a tmpfs:
tmpfs: - /run/channelwatch:mode=0750,uid=0,gid=1000Next steps
Section titled “Next steps”- First-Run Configuration - add your Channels DVR server and configure alerts
- Multi-DVR Setup - monitor multiple Channels DVR servers from one instance
- Notification Providers - compare Pushover, Discord, Telegram, and more