1. Goal
- Enable local recording of Ring camera streams.
- Phase 1: Continuous recording.
- Phase 2: Motion-triggered recording (battery/storage friendly).
2. Environment
- Host: Ubuntu/Debian server or VM
- Docker / Docker Compose installed
- Ring camera already linked in the Ring app
- Testbed used: local VM (same steps apply to production).
3. Core Configuration Files
MQTT broker
mosquitto/mosquitto.conf
listener 1883
allow_anonymous true
Ring-MQTT
ring-mqtt/config.json
{
"mqtt_url": "mqtt://mqtt",
"mqtt_options": {
"username": "xxx@mail.com",
"password": "yyy"
},
"ring_token": ""
}
⚠️ Note: ring_token is obtained via WebUI (http://<host_ip>:55123/). Do not expose the actual value.
Docker Compose
docker-compose.yml
version: "3.8"
services:
mqtt:
image: eclipse-mosquitto
container_name: mosquitto
restart: unless-stopped
ports:
- "1883:1883"
volumes:
- ./mosquitto/mosquitto.conf:/mosquitto/config/mosquitto.conf
ring-mqtt:
image: tsightler/ring-mqtt
container_name: ring-mqtt
restart: unless-stopped
depends_on:
- mqtt
ports:
- "8554:8554" # RTSP 流端口
- "55123:55123" # Web UI 端口
volumes:
- ./ring-mqtt:/data
4. Steps
- Start services:
docker compose up -d - Check Ring-MQTT logs:
docker logs -f ring-mqtt→ Access WebUI athttp://<host_ip>:55123/and generate your Ring token. - Test recording manually:
ffmpeg -i rtsp://localhost:8554/<DEVICE_ID>_live -t 30 test.mp4 - Verify recordings are saved under
./recordings/.
5. Common Issues & Fixes
- Cannot connect RTSP → Ensure token generated & container restarted.
- Recorder container fails → Use correct
<DEVICE_ID>_liveinstead of camera name. - Files not saved → Check
docker logs -f ring-recorder, confirm volume mounts.
6. Security Considerations
- Always hide
ring_tokenand<DEVICE_ID>in public configs. - Avoid continuous 24/7 recording if using battery-powered Ring devices.
- Plan for storage growth if recording continuously.
7. Advanced Reference (Motion-triggered Recording)
By default, recording runs continuously, which can drain battery.
With MQTT events, we can start recording only when motion is detected.
Script Example
record_on_motion.sh
#!/bin/bash
DEVICE_ID="<DEVICE_ID>" # Camera ID (hidden)
DURATION=90 # 每次录制时长(秒)
SAVE_PATH="./recordings"
LOG_FILE="./record_on_motion.log"
mkdir -p "$SAVE_PATH"
log() {
MSG="[$(date +"%Y-%m-%d %H:%M:%S")] $1"
echo "$MSG" | tee -a "$LOG_FILE"
}
# 持续订阅 motion 事件
mosquitto_sub -h localhost -t "ring/+/camera/$DEVICE_ID/motion/state" | while read state
do
if [ "$state" == "ON" ]; then
TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
FILE="$SAVE_PATH/Front_$TIMESTAMP.mp4"
log "Motion detected, start recording: $FILE (duration $DURATION seconds)"
ffmpeg -rtsp_transport tcp -i rtsp://localhost:8554/${DEVICE_ID}_live \
-t $DURATION -c copy "$FILE" >>"$LOG_FILE" 2>&1
log "Recording finished: $FILE"
fi
done
⚠️ Replace <DEVICE_ID> with your Ring camera’s internal ID.
Usage
chmod +x record_on_motion.sh
./record_on_motion.sh
→ When motion is detected, a short recording is automatically created.
8. Directory Layout
~/dev/ring
├── docker-compose.yml
├── record_on_motion.sh
├── mosquitto
│ ├── data
│ ├── log
│ └── mosquitto.conf
├── recordings
└── ring-mqtt
├── config.json
├── go2rtc.yaml
└── ring-state.json
9. Appendix: Port Explanations
MQTT → 1883
- Purpose: Message broker for events (motion, doorbell).
- Who connects:
record_on_motion.sh, Home Assistant, automation systems.
WebUI → 55123
- Purpose: Token generation interface for Ring authentication.
- Who connects: You (via browser, one-time login).
RTSP → 8554
- Purpose: Provides camera video stream as RTSP.
- Who connects:
ffmpeg, VLC, recording service.
Quick Reference Table
| Port | Protocol/Service | Function | Who Uses It |
|---|---|---|---|
| 1883 | MQTT broker | Transmit event messages | Motion script, Home Assistant, automations |
| 55123 | WebUI (HTTP) | Generate/manage Ring token | You (browser login) |
| 8554 | RTSP video stream | Provide live video stream | ffmpeg, VLC, recording service |