Home Surveillance with MotionEyeOS

Home Surveillance with MotionEyeOS

I spent two weekends fighting with consumer camera apps, cloud subscriptions, and mandatory internet connectivity. Then I discovered MotionEyeOS, and everything changed. If you want a privacy-first, fully self-hosted video surveillance system that actually works on cheap hardware, this is the guide you need.

Why MotionEyeOS Over Cloud Cameras?

Every mainstream security camera pushes you toward cloud storage. Wyze, Ring, Arlo—they all want your footage in their servers, behind their terms of service. When I set this up, I had three hard requirements: local storage only, no subscription fees, and the ability to access my footage from anywhere on my network without cloud infrastructure.

MotionEyeOS is a lightweight, headless Linux distribution that turns a Raspberry Pi, old laptop, or NUC into a full surveillance hub. It supports USB webcams, IP cameras, and even Raspberry Pi camera modules. You get motion detection, scheduled recording, multi-camera dashboards, and a clean web interface. Better yet, everything stays on your hardware.

Hardware Requirements

I run this on a Raspberry Pi 4 with 2GB RAM and a 64GB microSD card. That handles three 1080p IP cameras with motion detection enabled. Here's what I'd recommend:

For cameras, I prefer affordable ONVIF-compliant IP cameras like the Reolink RLC-410 or Amcrest UltraHD. USB webcams work too, but they eat more CPU.

Installation on Raspberry Pi

The easiest path is using the pre-built MotionEyeOS image. It's a complete, minimal OS that boots directly into the motion eye service.

#!/bin/bash
# Download the MotionEyeOS image for Pi 4
wget https://github.com/motioneye-project/motioneyeos/releases/download/20231219/motioneyeos-20231219-rpi4.img.xz

# Extract the image
unxz motioneyeos-20231219-rpi4.img.xz

# Write to microSD (replace /dev/sdb with your device)
sudo dd if=motioneyeos-20231219-rpi4.img of=/dev/sdb bs=4M conv=fsync
sync

# Eject and boot
sudo eject /dev/sdb

Insert the SD card into your Pi, power it on, and wait about two minutes for first boot. Find the Pi's IP address on your network (check your router), then navigate to http://pi-ip-address:8081. The default username is admin with no password. Change this immediately in settings.

Watch out: MotionEyeOS has no password by default. This is a security risk if your network is exposed. Set a strong password and consider restricting access to your local network only.

Adding and Configuring Cameras

Once you're logged in, adding a camera is straightforward. I'll walk through an IP camera setup, as that's most flexible.

#!/bin/bash
# Example: Testing camera connectivity before adding to MotionEyeOS
# Replace 192.168.1.100 with your camera IP
# Default credentials vary by brand (check manual)

# Test RTSP stream
ffprobe -v error -select_streams v:0 \
  -show_entries stream=width,height,r_frame_rate \
  -of default=noprint_wrappers=1 \
  rtsp://admin:[email protected]:554/stream1

# If that works, your camera is reachable

In the MotionEyeOS web interface, click the plus icon to add a camera. Select "IP Camera" and enter:

Once added, the live feed appears on your dashboard. I have three cameras running simultaneously with zero CPU concerns on the Pi 4.

Motion Detection and Recording

This is where MotionEyeOS shines. Click into any camera's settings and configure motion detection:

For recording, I enable "Capture mode" with "Motion Detection" selected. This saves clips only when motion is detected, conserving storage. You can also set a schedule—record continuously 9–5 PM, motion detection only at night.

Tip: If you're storing on a USB drive, test it first with `hdparm -tT /dev/sdb1` to ensure it's fast enough. Slow USB drives cause dropped frames on multi-camera setups.

Storage and Backup Strategy

By default, MotionEyeOS stores videos to the SD card. That fills up fast with motion clips. I mount a USB external drive and configure MotionEyeOS to write there instead.

In the web interface, go to Settings > Storage and point the path to your mounted external drive (typically `/mnt/usb-drive`). For redundancy, I set up a weekly rsync job to pull backups to my NAS:

#!/bin/bash
# Cron job: Weekly backup of MotionEyeOS recordings
# Add this to your backup server's crontab

0 2 * * 0 rsync -av --delete \
  192.168.1.50:/mnt/usb-drive/motioneye/ \
  /mnt/nas/surveillance-backup/ \
  --exclude '*.tmp' >> /var/log/motioneyeos-backup.log 2>&1

# Run via cron: crontab -e

Remote Access Without Cloud

MotionEyeOS has a built-in cloud relay option (motioneye.io), but I avoid it entirely. Instead, I use Tailscale for secure remote access. My MotionEyeOS instance joins my Tailscale network, and I access it at http://motioneyeos.myhomelab:8081 from anywhere.

If you prefer traditional port forwarding, you can open port 8081 on your router and use dynamic DNS. I don't recommend this for security reasons—Tailscale is simpler and more secure.

Performance and Multi-Camera Considerations

I run three 1080p cameras on a Pi 4 (2GB) without issues. Live view is responsive, motion detection is instant, and CPU sits around 35–45%. A few tweaks help:

If you plan to run 6+ cameras, I'd recommend moving to an old x86 mini PC or upgrading to a Pi 5. The jump in transcoding capability is worth it.

Maintenance and Updates

MotionEyeOS updates automatically if you enable it in settings. I check once a month to ensure everything's still running. The log viewer (in the web UI) is invaluable for debugging camera connection drops.

Also, clean your camera lenses. Dusty lenses break motion detection and make recordings useless. I use a soft lens cloth weekly.

Next Steps

Once you have MotionEyeOS running smoothly, consider adding automation: trigger a Philips Hue light or send a notification to Home Assistant when motion is detected. You could also layer in Frigate for AI-powered person detection, but that's a separate build.

This setup gives you a professional surveillance system for under $150 in hardware, zero subscription fees, and complete privacy. That's worth the weekend of tinkering.

```