ClDemoe/camera live view app dl yme
Home camera stack
Frigate NVR + Mosquitto MQTT + frigate-notify -> ntfy push notifications, with face recognition and license plate recognition on the Frigate side. Includes a planned Pi Zero W "doorbell speaker" stack (push-to-talk web page fronted by Caddy) that's wired but not yet deployed.
Architecture
Cameras (RTSP) Phone / browser
| |
v v
+------------+ MQTT events +----------------+ +-------------+
| Frigate | <-------------> | Mosquitto | | Pi |
| (NVR) | | broker | | (planned) |
+-----+------+ +-------+--------+ | speaker |
| WebRTC / MSE | +------+------+
v v ^
+------------+ +------------------+ |
| Caddy |<--HTTPS--------| frigate-notify | |
| proxy | | (event consumer) | |
+------------+ +--------+---------+ |
| | |
| cam.yourdomain.com ntfy push |
| doorbell.yourdomain.com |
+-------HTTPS---------------> PTT button ------------+
What's deployed vs planned
| Component | Status |
|---|---|
| Frigate 0.17 | Deployed |
| Mosquitto MQTT broker | Deployed |
| frigate-notify -> ntfy | Deployed |
| Face recognition | Configured, needs training |
| License plate recognition | Configured |
| Caddy reverse proxy | Whatever your existing Caddy does |
| Pi Zero W doorbell speaker | Planned, not deployed yet |
Repo layout
home-cameras/
|-- docker-compose.yml # frigate + mosquitto + frigate-notify
|-- .env.example # template -- copy to .env, fill in
|-- .gitignore
|-- README.md # this file
|
|-- frigate_config/
| |-- config.yml # production: main stream for detect
| `-- alternatives/
| `-- config-simple.yml # lower-CPU fallback: sub-stream detect
|
|-- frigate-notify/
| `-- config.yml # MQTT in, ntfy out, face-aware templates
|
|-- mosquitto/
| |-- config/
| | `-- mosquitto.conf # broker config (allow_anonymous false)
| |-- data/.gitkeep
| `-- log/.gitkeep
|
|-- caddy/
| `-- Caddyfile # reverse proxy for both subdomains
|
`-- pi/ # runs on the Pi, NOT on the Frigate host
|-- README.md # Pi-specific setup
|-- server.py # Flask + WebSocket PTT receiver
|-- doorbell.service # systemd unit
`-- install.sh # one-shot installer
First-run on the Frigate host
Prerequisites:
- Docker + docker compose v2
- DNS records for any subdomains you intend to use, pointing at your Caddy host
- An existing Caddy instance (separate from this stack) handling TLS at the edge, OR adapt for whatever reverse proxy you use
- Coral USB stick plugged in (or adjust
detectors:for a different accel) - A media disk mounted on the host; update the
/media/frigatepath indocker-compose.yml
Steps:
git clone https://github.com/YOU/home-cameras.git
cd home-cameras
# 1) Configure secrets
cp .env.example .env
$EDITOR .env
# 2) Make mosquitto dirs writable by the container's mosquitto user (UID 1883)
sudo chown -R 1883:1883 mosquitto/
# 3) Bootstrap mosquitto BEFORE applying the production config.
# The committed mosquitto.conf has allow_anonymous false + password_file,
# which means we need to create the password file first OR temporarily
# flip to allow_anonymous true to start.
#
# Easiest: temporarily edit mosquitto/config/mosquitto.conf:
# allow_anonymous false -> allow_anonymous true
# comment out: password_file /mosquitto/config/passwd
# Then start:
docker compose up -d mosquitto
docker compose logs mosquitto --tail 10 # expect "running"
# 4) Create the MQTT user (use the password from your .env)
docker compose exec mosquitto mosquitto_passwd -c -b \
/mosquitto/config/passwd frigate \
"$(grep ^FRIGATE_MQTT_PASSWORD .env | cut -d= -f2)"
sudo chown 1883:1883 mosquitto/config/passwd
sudo chmod 0640 mosquitto/config/passwd
# 5) Restore mosquitto.conf to its committed state:
# allow_anonymous true -> allow_anonymous false
# uncomment: password_file /mosquitto/config/passwd
git checkout mosquitto/config/mosquitto.conf
docker compose restart mosquitto
# 6) Verify auth works
sudo apt install -y mosquitto-clients
mosquitto_sub -h 127.0.0.1 -u frigate \
-P "$(grep ^FRIGATE_MQTT_PASSWORD .env | cut -d= -f2)" \
-t 'test/#' -v &
mosquitto_pub -h 127.0.0.1 -u frigate \
-P "$(grep ^FRIGATE_MQTT_PASSWORD .env | cut -d= -f2)" \
-t 'test/hello' -m 'ok'
# expect: test/hello ok
kill %1
# 7) Bring up the rest
docker compose up -d
docker compose logs -f
Healthy startup looks like:
- Frigate:
frigate.comms.mqtt INFO : MQTT connected - frigate-notify:
Successfully connected to http://frigate:5000thenConnected to MQTT.thenSubscribed to MQTT topic: frigate/events - mosquitto: incoming client connections from both
Caddy
On whichever host runs Caddy, copy caddy/Caddyfile (or merge the relevant
site blocks into your existing one), edit IPs and domains, then:
sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy
Until the Pi is deployed, comment out the doorbell.yourdomain.com block.
Train face recognition
- Let Frigate run with normal foot traffic for a day. Face crops are captured automatically and appear under Face Library -> Train in the Frigate UI.
- For each person, label 5-10 diverse clear crops -- different angles, lighting, times of day. Diversity beats quantity; 30 near-identical frames from one event hurts recognition.
- Walk past the camera again. Events should now show the person's name as the sub-label, and frigate-notify's ntfy push will say their name instead of "person".
Training images live on the Frigate host at
/media/frigate/clips/faces/<n>/. Not version-controlled (privacy).
Switching config profiles
This repo ships with two Frigate configs:
frigate_config/config.yml-- active. Main 2688x1520 stream for both detect and record. Better face recognition at distance, higher CPU.frigate_config/alternatives/config-simple.yml-- lower-CPU fallback. Sub-stream 640x480 for detect, main for record only.
To switch:
cp frigate_config/config.yml frigate_config/config.yml.bak
cp frigate_config/alternatives/config-simple.yml frigate_config/config.yml
docker compose restart frigate
Adding a camera with a mic
When adding a camera with a built-in microphone (e.g. an Anpviz with mic),
see the comment block at the bottom of frigate_config/config.yml for the
exact edits needed to enable live audio in the Frigate UI.
Pi doorbell speaker (when you're ready)
See pi/README.md. Summary:
- Flash Pi OS Lite, scp
pi/to the Pi, runinstall.sh. - Add the
doorbell.yourdomain.comsite block in Caddy. - Open the URL on your phone.
Security notes
.envhas RTSP credentials, MQTT password, ntfy URL. Never commit it. This repo's.gitignoreblocks it; reviewgit statusbefore committing.- The Pi's Flask server binds only to
127.0.0.1. Caddy is what exposes it. Do NOT bindserver.pyto0.0.0.0-- it has no auth of its own. - Mosquitto's port 1883 is LAN-only. Use a VPN for any remote MQTT clients.
- For the doorbell page, optionally add basic auth in Caddy (
caddy hash-password).
Troubleshooting
Frigate can't reach cameras
docker compose exec frigate ping -c 2 <camera_ip>
RTSP path varies by camera vendor:
- Dahua / Amcrest:
/cam/realmonitor?channel=1&subtype=0 - Hikvision / Anpviz H-series:
/Streaming/Channels/101
If your password contains %, @, /, ?, #, &, or +, either
URL-encode it or change the password to avoid those characters.
Mosquitto restarts in a loop
Almost always permission on mosquitto/config/passwd:
sudo chown -R 1883:1883 mosquitto/
sudo chmod 0640 mosquitto/config/passwd
docker compose restart mosquitto
Or the config file or password file simply doesn't exist yet -- see the "First-run on the Frigate host" section above for the bootstrap flow.
frigate-notify connects to MQTT but doesn't send pings
docker compose logs frigate-notify --tail 30
- "webapi" in logs but expecting MQTT? Check
webapi.enabled: falseandmqtt.enabled: trueinfrigate-notify/config.yml. - MQTT auth fails? Verify
FN_FRIGATE__MQTT__PASSWORD(note DOUBLE underscores) matches what you set withmosquitto_passwd. - Confirm what reached the container:
docker inspect frigate-notify --format '{{range .Config.Env}}{{println .}}{{end}}' | grep FN_
Always see "person" instead of trained name
- Increase
alerts.general.recheck_delayinfrigate-notify/config.ymlfrom 10 to 15 or 20 seconds. - Check the Frigate UI event timeline -- if the event itself doesn't show a sub_label, the face crop was too small / too blurry / too obscured for recognition.
Hardware reference
Current:
- NVR host: x86_64 + Docker, USB Coral
- Cameras: Amcrest (Dahua RTSP)
- Notifier: self-hosted ntfy
Planned:
- Anpviz 4K camera with built-in mic (front door audio)
- Back door + squirrel feeder cameras
- Pi Zero W + USB speaker at the door