Skip to main content

Moonfire NVR

Moonfire NVR on inoCORE5 (Raspberry Pi CM5)

https://github.com/scottlamb/moonfire-nvr

Overview

Moonfire NVR is an open-source network video recorder designed to be lightweight, efficient and easy to integrate. It records H.264-over-RTSP streams from IP cameras directly to disk without decoding or re-encoding video frames, which keeps CPU usage extremely low even on small ARM boards.

Moonfire NVR uses a hybrid storage format:

  • Video frames are stored as files in a directory tree on spinning disk or SSD.
  • Metadata (timestamps, segments, indexes) are stored in a SQLite3 database on flash.

On top of this, it can construct .mp4 files for arbitrary time ranges on the fly, using the stored H.264 frames and metadata. This makes it ideal for long-term storage and on-demand clip export.

Despite its simplicity, Moonfire NVR can handle multiple Full HD streams at 30 fps on low-power hardware (e.g., 6× 1080p/30 on a Raspberry Pi-class board) while using only a small fraction of total CPU.

The web interface is intentionally minimal:

  • Filterable list of recorded segments
  • Basic trimming/export for arbitrary time ranges
  • Experimental live view for real-time monitoring

This fits perfectly with the philosophy of inovaea: minimal bloat, maximal reliability, and easy integration into higher-level systems.


Key Features

  • Very low CPU usage
    No decoding, analysis or re-encoding of video frames; Moonfire works directly with H.264 frames received via RTSP.

  • Efficient storage
    Hybrid design: raw video frames in a directory, metadata in SQLite. Easy to back up and move.

  • Scales on small hardware
    Proven to work with multiple 1080p streams on Raspberry Pi-class hardware with < 10% CPU load (depends on cameras and network).

  • On-the-fly MP4 export
    Generate .mp4 files for arbitrary time ranges without re-encoding.

  • Simple web UI
    Filterable list of segments, trimming/export, experimental live view.

  • Open-source and extensible
    Source code available, active development, easy to integrate into your automation or monitoring stack.


Role in the inovaea Architecture

Within the inovaea ecosystem, Moonfire NVR acts as a lightweight recording backend for IP cameras:

  • records and indexes all video streams,
  • exposes a simple HTTP API and web UI,
  • serves stored clips or dynamically generated MP4 segments on demand,
  • integrates with higher-level inovaea services (dashboards, alarm systems, IoT platforms).

Typical use cases:

  • camera recording for buildings, industrial halls and sites,
  • edge recording on local hardware (inoCORE5) with optional replication to NAS or cloud,
  • providing video evidence for events generated by other inovaea components (sensors, alarms, PLCs).

Hardware Platform: inoCORE5

The inoCORE5 module is based on the Raspberry Pi Compute Module 5 (CM5) and provides:

  • ARM64 CPU suitable for continuous multi-camera recording,
  • on-board storage (eMMC or external SSD),
  • Ethernet for IP cameras and backend connectivity,
  • GPIO / expansion for integration with inovaea and other systems.

From the Moonfire NVR point of view, inoCORE5 behaves like a headless Raspberry Pi with 64-bit Linux, usually running Raspberry Pi OS or Debian.


Step-by-Step Installation on inoCORE5

Note

Commands assume a 64-bit Raspberry Pi OS / Debian-like system with sudo available and network access. Run these in an SSH session or console on the inoCORE5 device.

  1. System Preparation

Update your system and install some basic tools:

sudo apt update
sudo apt upgrade -y

sudo apt install -y git curl build-essential pkg-config \
libssl-dev libsqlite3-dev libclang-dev clang
  1. Install Rust Toolchain

Moonfire NVR is written in Rust. The recommended way to install Rust is via rustup:

curl https://sh.rustup.rs -sSf | sh -s -- -y
source "$HOME/.cargo/env"

Check that Rust is installed:

rustc --version
cargo --version

You should see version strings printed.

  1. Download Moonfire NVR Source Clone the Moonfire NVR repository:
cd ~
git clone https://github.com/scottlamb/moonfire-nvr.git
cd moonfire-nvr

(If you are using a specific fork or inovaea mirror, adjust the URL accordingly.)

  1. Build a Release Binary Build Moonfire NVR in release mode:
cargo build --release

When compilation finishes, the binary will be located at:

target/release/moonfire-nvr

Install it to a global location:

sudo cp target/release/moonfire-nvr /usr/local/bin/
sudo chmod 755 /usr/local/bin/moonfire-nvr
  1. Create User and Directories Create a dedicated system user for Moonfire NVR:
sudo useradd --system --no-create-home --shell /usr/sbin/nologin moonfire

Create directories for configuration, database and video files:

sudo mkdir -p /etc/moonfire-nvr
sudo mkdir -p /var/lib/moonfire-nvr/db
sudo mkdir -p /var/lib/moonfire-nvr/video

Set ownership:

sudo chown -R moonfire:moonfire /etc/moonfire-nvr /var/lib/moonfire-nvr

Basic Configuration Examples

We’ll use a TOML-style configuration file placed at:

sudo nano /etc/moonfire-nvr/config.toml
warning

⚠️ The exact schema may differ between Moonfire NVR versions.
Treat this as a conceptual example and adjust according to the official documentation of the version you use.

note

The exact schema may differ between Moonfire NVR versions.
Always verify details in the official documentation of the version you use.

  1. Global Storage Settings
[data]
db_dir = "/var/lib/moonfire-nvr/db"
video_dir = "/var/lib/moonfire-nvr/video"

This tells Moonfire NVR where to store:

  • the SQLite database (db_dir),
  • the video frame files (video_dir).
  1. Example Camera with RTSP Stream

Let’s assume an IP camera with:

  • IP: 192.168.10.50
  • username: nvr
  • password: secret
  • main stream path: /h264 on port 554

Add a camera block:

[camera.front_door]
name = "Front door"
enabled = true
rtsp_url = "rtsp://nvr:secret@192.168.10.50:554/h264"

# Recording strategy
record_mode = "continuous" # or "schedule", "motion" – depending on version support
retain_days = 14 # how long to keep recording

# Optional: tags or notes for integration
tags = ["building-A", "entry"]
  1. Example Camera Storing to a Separate Disk

If you mount an external SSD or HDD at /mnt/nvr-video, you can point video storage there to avoid wearing out internal flash:

[data]
db_dir = "/var/lib/moonfire-nvr/db"
video_dir = "/mnt/nvr-video"

Ensure the mount is present in /etc/fstab and mounted before the Moonfire service starts.

  1. MP4 Export Concept (via HTTP)

Moonfire NVR exposes an HTTP API / web UI. A typical pattern for MP4 export looks like:

curl "http://ino-core5-nvr.local:8080/api/clip.mp4?camera=front_door&start=2025-12-01T10:00:00Z&end=2025-12-01T10:10:00Z" \
-o front-door-10min.mp4

Adjust the exact path and query parameters to match the version you are using (route, parameter names and timestamp format may differ). The key idea:

  • specify the camera,
  • define start and end timestamps,
  • download the generated .mp4 file.

This can then be integrated into inovaea services (automatic export for incidents, daily snapshot exports, etc.).


Systemd Service Setup

Create a systemd service to run Moonfire NVR as a background service.

sudo nano /etc/systemd/system/moonfire-nvr.service

Example service file:

[Unit]
Description=Moonfire NVR service
After=network.target

[Service]
User=moonfire
Group=moonfire
ExecStart=/usr/local/bin/moonfire-nvr --config /etc/moonfire-nvr/config.toml
WorkingDirectory=/var/lib/moonfire-nvr
Restart=on-failure
RestartSec=5

# Security hardening (optional)
NoNewPrivileges=true
ProtectSystem=full
ProtectHome=true

[Install]
WantedBy=multi-user.target

Reload systemd and enable the service:

sudo systemctl daemon-reload
sudo systemctl enable moonfire-nvr
sudo systemctl start moonfire-nvr

Check status:

sudo systemctl status moonfire-nvr

If everything is correct, Moonfire NVR should now run in the background and expose its web interface on a configurable port (often 8080 or similar, depending on your config/flags).


Architectural Integration Diagram (Concept)

You can use this Mermaid diagram directly in your docs (Docusaurus / MkDocs with Mermaid support):

flowchart LR
subgraph Cameras
CAM1[IP Camera 1]
CAM2[IP Camera 2]
CAM3[IP Camera N]
end

CAM1 -->|RTSP / H.264| NVR[Moonfire NVR on inoCORE5]
CAM2 -->|RTSP / H.264| NVR
CAM3 -->|RTSP / H.264| NVR

NVR --> VIDEO[/Video storage (SSD / HDD)/]
NVR --> DB[(SQLite metadata DB)]

NVR --> UI{{Moonfire Web UI / HTTP API}}

UI --> INO_CLOUD[(inovaea backend / services)]
UI --> USERS[Operators / Web clients]

INO_CLOUD --> DASH[Dashboards, events, automation]

This illustrates:

  • cameras sending RTSP/H.264 to Moonfire NVR on inoCORE5,
  • hybrid storage (video + SQLite),
  • web UI / HTTP API,
  • integration with inovaea backend and user interfaces.

Banner Concept for Documentation

You can use this as a briefing / prompt for a designer or an image generator:

Banner idea: Wide, modern, minimalistic banner. Dark or navy-blue background with subtle grid lines and a hint of a circuit board pattern. On the left side: stylized outline icons of IP cameras with RTSP arrows pointing toward a compact embedded board labeled “inoCORE5”. On the right: stacked disks (storage) and a small web browser window showing a simple video timeline. Text overlay: “Moonfire NVR on inoCORE5 – Lightweight IP camera recording for inovaea” Style: clean, flat, slightly isometric, no real-life photos, suitable for technical documentation.

If you want, I can also:

adapt this text into Docusaurus front-matter + sidebar structure,

add advanced config examples (retention policies, multiple storage tiers, tagging, etc.),

or prepare short API integration snippets (Python/Node) for automatic MP4 export into inovaea workflows.