21+ years in hosting · Jaipur, India · INR billing with 18% GST · 24/7 email support
Blog · WebJi® India

Self-Hosted CCTV Server

Quick answer

A self-hosted CCTV server is a Linux machine you control that records RTSP streams from IP cameras with Frigate, ZoneMinder or MotionEye. One 4 Mbps camera writes about 43 GB a day. Keep the recorder on the camera network, view it over WireGuard, and use a VPS only as a relay or off-site copy.

For shop owners, home users and IT staff replacing a closed NVR with open software they run themselves.

✓ In business since 2005
✓ INR + GST billing
✓ 24/7 Email Support — avg reply < 60 min
GuideWebJi®
knowledge
Read time
5 min
Sections
7
Updated
14 Nov 2026
Written by
WebJi® team

What is a self-hosted CCTV server?

A self-hosted CCTV server is a Linux machine you control that pulls video from IP cameras, records it to its own disk and lets you watch live and recorded footage without a vendor cloud or monthly subscription. It replaces the closed DVR/NVR box with open software such as Frigate, ZoneMinder or MotionEye.

  • Cameras: IP cameras that publish an RTSP stream on the local network and, ideally, support ONVIF for discovery. Most PoE cameras from Hikvision, Dahua, Reolink and Amcrest do; many consumer “cloud only” cameras do not.
  • Recorder: a Linux host running Docker, with a disk sized for your retention period and enough CPU (or a GPU/accelerator) to decode the streams.
  • Remote access: a private VPN tunnel such as WireGuard or Tailscale, never a port forwarded from the router to the recorder.

Frigate vs ZoneMinder vs MotionEye

Choose Frigate for AI object detection and useful alerts, ZoneMinder for classic continuous NVR recording and PTZ control on larger installs, and MotionEye for two or three cameras on modest hardware. All three are free and open source.

Self-hosted CCTV recorders compared
SoftwareLicenceHow it decides what to keepBest for
FrigateMITObject detection (people, vehicles, animals) plus motion; keeps alerts and detections longer than plain motionHomes and shops that want alerts that mean something
ZoneMinderGPLContinuous or motion-triggered recording with a MySQL/MariaDB databaseLarger sites, PTZ cameras, traditional NVR workflows
MotionEyeGPLLightweight motion detection, simple web UITwo or three cameras on a small board or old PC

Frigate bundles go2rtc, which restreams each camera so the recorder and the live view share one connection to the camera. It writes recordings straight from the camera stream without re-encoding, which keeps CPU use down.

How much storage does CCTV recording need?

Storage depends on bitrate and retention, not megapixels: one camera at 4 Mbps writes about 43 GB a day, so four cameras recording 24/7 for 30 days need roughly 5.2 TB. The arithmetic is bitrate × 86,400 seconds ÷ 8 bits, then × cameras × days.

Continuous CCTV storage by camera bitrate (decimal GB/TB)
Bitrate per cameraOne camera, one dayFour cameras, 30 daysEight cameras, 30 days
2 Mbps21.6 GB2.6 TB5.2 TB
4 Mbps43.2 GB5.2 TB10.4 TB
6 Mbps64.8 GB7.8 TB15.6 TB
8 Mbps86.4 GB10.4 TB20.7 TB

Frigate's continuous recording is off by default; you choose how long each kind of footage is kept. This configuration keeps motion footage for 3 days and anything that triggered an alert or detection for 30, which uses far less disk than 24/7 recording, depending on how busy the scene is:

record:
  enabled: true
  motion:
    days: 3
  alerts:
    retain:
      days: 30
      mode: motion
  detections:
    retain:
      days: 30
      mode: motion

If the disk drops below roughly one hour of recording space, Frigate deletes the oldest footage regardless of retention settings, so size the disk for the retention you set and keep other data off it.

What hardware does a CCTV server need for 4 or 8 cameras?

Decoding video is the main load, so a 4-camera Frigate box needs more CPU than a file server, and 8 cameras practically need hardware video decoding plus a detection accelerator such as a Coral TPU or an Intel GPU. Treat the figures below as a starting point and check CPU use with your own streams.

Starting-point recorder sizing for 4 MP cameras
CamerasCPU / RAMDiskNotes
4 × 4 MP4 cores / 8 GBSSD for OS + 2–6 TB for footageCPU detection works; an accelerator cuts CPU sharply
8 × 4 MP8 cores / 16 GBSSD for OS + 4–12 TB for footageUse hardware decoding and an accelerator

Frigate keeps decoded frames in shared memory, and Docker's default of 64 MB is too small for more than a couple of cameras; the result is “Bus error” crashes. Frigate's documentation sizes it from the detect resolution: (width × height × 1.5 + 270,480) ÷ 1,048,576 × 25 frames per camera, plus about 50 MB for logs and cache. Four 1280×720 detect streams, with room for two more cameras, come to roughly 290 MB, so shm_size: "512mb" is comfortable. Run detection on a low-resolution substream and record the main stream.

How to set up Frigate with Docker Compose

Frigate runs as one Docker container: map a config folder and a footage disk, set the shared-memory size, then list each camera's RTSP URLs in config.yml. An MQTT broker is optional unless you use Home Assistant.

services:
  frigate:
    container_name: frigate
    image: ghcr.io/blakeblackshear/frigate:stable
    restart: unless-stopped
    shm_size: "512mb"
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ./config:/config
      - /mnt/cctv:/media/frigate
      - type: tmpfs
        target: /tmp/cache
        tmpfs:
          size: 1000000000
    ports:
      - "8971:8971"
mqtt:
  enabled: false
cameras:
  shop_front:
    ffmpeg:
      inputs:
        - path: rtsp://viewer:PASSWORD@192.168.1.20:554/stream1
          roles: [record]
        - path: rtsp://viewer:PASSWORD@192.168.1.20:554/stream2
          roles: [detect]
    detect:
      width: 1280
      height: 720

RTSP paths differ by camera brand; check the camera's manual or ONVIF device info for the main and substream URLs. Use a dedicated low-privilege camera account rather than the admin password. Port 8971 is Frigate's authenticated web UI; port 5000 is unauthenticated and should not be exposed outside the Docker network. Docker basics are in what a Docker container is.

How to view CCTV remotely without port forwarding

Join the recorder and your phone to the same WireGuard network, for example with Tailscale, and open the recorder's private address; nothing on the router is opened to the internet. Port-forwarded NVR web interfaces are a common way camera systems end up in botnet scans.

  1. On the recorder: curl -fsSL https://tailscale.com/install.sh | sh, then sudo tailscale up and sign in.
  2. Note the stable 100.x.y.z address Tailscale assigns to the recorder.
  3. Install the Tailscale app on your phone and sign in to the same account.
  4. Open https://100.x.y.z:8971 and log in to Frigate. The browser warns once because Frigate serves port 8971 with its own self-signed certificate by default; that is expected inside a private tunnel.
  5. Keep the router closed: no forwarding of 8971, 5000 or 554, and the host firewall denying inbound by default.

The test that proves it is private: the live view loads over mobile data with Tailscale on, and fails with Tailscale off.

Should the CCTV recorder run on a VPS?

Usually no: keep the recorder on the camera network and use a VPS as a WireGuard relay or an off-site copy of important clips. Streaming every camera to a data centre needs sustained upload (four 4 Mbps cameras need about 16 Mbps continuously), and recording stops whenever the site's internet link drops.

Frigate's own documentation recommends Docker on bare-metal Debian-based Linux and advises against running it inside a virtual machine, because detection accelerators and GPUs need low-overhead hardware access; a typical VPS has neither, so detection would be CPU-only. Where a VPS does earn its place:

  • Relay: when the site sits behind carrier-grade NAT, a small VPS running WireGuard gives both ends a fixed meeting point. A Linux VPS with root access does this; WebJi® lists VPS plans from ₹499 a month plus GST (published price read 29 October 2026; checkout confirms the current figure).
  • Off-site copy: sync exported alert clips to storage that is not the recorder's disk, so theft or fire at the site does not take the evidence with it. Server backup solutions cover that storage, and the 3-2-1 backup rule explains why.

WebJi® sells the server, not a managed CCTV service or camera hardware. Running other tools on the same box is covered in self-hosted automation tools.

FAQ

Frequently asked questions

Can old DVR analog cameras work with Frigate or ZoneMinder?

Only through a device that turns them into network streams. Many DVRs publish an RTSP stream per channel, which Frigate or ZoneMinder can record. If the DVR has no RTSP output, the analog cameras need an encoder or replacement IP cameras.

Should cameras record H.264 or H.265?

H.265 uses less disk for the same quality, but Frigate notes that H.265 recordings play only in Chrome 108+, Edge and Safari; other browsers need H.264. If you view footage on varied devices, H.264 is the safer default.

Why does Frigate crash with “Bus error”?

Usually because the container's shared memory is too small for the number and resolution of detect streams. Raise shm_size using Frigate's formula. If that does not help, the container may be hitting its process or open-file limits, which Docker Compose can raise.

Is it legal to self-host CCTV footage in India?

Recording your own premises is common, but footage of identifiable people is personal data. Put up visible notices, limit cameras to your own property, restrict who can view recordings and delete them on a schedule. Take legal advice if you record employees or public areas.

Checked 14 November 2026 against Frigate 0.18 documentation · Reviewed by the WebJi® team, Jaipur.

WebJi® since 2005

Ready to get started with WebJi®?

Join 12,000+ businesses across India and overseas. INR pricing, 18% GST shown before payment and 24/7 email support in Hindi and English — average first reply under 60 minutes.