Post

The Final Piece To My Homelab Has Arrived

The Final Piece To My Homelab Has Arrived

The Final Piece To My Homelab Has Arrived

Introduction

The quest for the perfect homelab setup is a never-ending journey for infrastructure engineers. When Reddit user u/throwaway_homelab_2024 posted their media/file server and AI-powered NVR build, it resonated with thousands of sysadmins facing similar challenges. This project exemplifies the modern DevOps approach to self-hosted infrastructure – combining computational efficiency, specialized hardware acceleration, and intelligent resource management in a single compact system.

For professional DevOps engineers and system administrators, homelabs serve as critical learning environments where we:

  1. Test production-grade configurations risk-free
  2. Develop infrastructure-as-code patterns
  3. Experiment with cutting-edge technologies
  4. Build solutions that commercial products can’t match

The build in question combines three essential modern workloads:

  • Media streaming (Plex)
  • Network-attached storage
  • AI-enhanced security monitoring (via Frigate NVR + Google Coral)

This guide will deconstruct each component, analyze the architectural decisions, and provide a blueprint for implementing similar systems. We’ll focus on practical infrastructure management techniques, hardware/software optimization, and real-world operational considerations.

Understanding the Components

Hardware Breakdown and Technical Rationale

Computational Foundation (Intel i7-8700)

  • 6-core/12-thread CPU with 65W TDP
  • UHD Graphics 630 (supports Quick Sync Video)
  • Why it works: Balances media transcoding capabilities with power efficiency

GPU Acceleration (Intel Arc A310)

  • Entry-level discrete GPU with Xe architecture
  • AV1 hardware encoding/decoding
  • 6GB GDDR6 memory
  • Why it works: Offloads AI workloads from CPU while handling modern video codecs

AI Co-Processor (Coral M.2 Accelerator)

  • Edge TPU coprocessor for TensorFlow Lite models
  • 4 TOPS (trillion operations per second) at 2W power
  • Why it works: Dedicated object detection without taxing primary compute resources

Storage Controller (M.2 to SATA Adapter)

  • 6-port SATA III expansion
  • PCIe 3.0 x4 interface
  • Why it works: Enables high-density storage in compact ITX form factor

Software Architecture

The system runs three primary services:

  1. Plex Media Server
    • Media organization and streaming
    • Hardware-accelerated transcoding
  2. Network Video Recorder (Frigate NVR)
    • Real-time video analysis
    • Object detection with TensorFlow
    • Camera management
  3. File Services
    • SMB/NFS shares
    • ZFS storage pool (recommended configuration)

Why This Configuration Matters

ComponentTraditional ApproachModern ApproachBenefit
TranscodingCPU-onlyGPU + QuickSync5-8x energy efficiency
Object DetectionCloud processingCoral TPUZero latency, no data egress
StorageHardware RAIDZFS software RAIDCopy-on-write, checksumming
SecurityVendor cloudSelf-hosted NVRComplete data control

Prerequisites

Hardware Requirements

Minimum specification for similar builds:

ComponentMinimumRecommendedNotes
CPUIntel 7th Gen+Intel 10th Gen+Quick Sync Video support
RAM8GB DDR432GB DDR4ZFS ARC caching requirements
Storage2x4TB HDD4x12TB in RAID-Z1Use CMR drives, not SMR
GPUIntegratedIntel Arc A380+AV1 encode/decode capability
AI AcceleratorNoneCoral M.2/USBTPU recommended for Frigate
Network1GbE2.5GbE + VLANsIsolate camera traffic

Software Requirements

  • Operating System: Ubuntu Server 22.04 LTS (Linux 6.2+ kernel required for Intel Arc GPUs)
  • Container Runtime: Docker 24.0+ with NVIDIA Container Toolkit
  • Key Packages:
    1
    2
    3
    4
    5
    6
    7
    8
    
    sudo apt-get install -y \
      linux-modules-extra-$(uname -r) \
      intel-opencl-icd \
      intel-level-zero-gpu \
      level-zero \
      libigc-dev \
      libigdfcl-dev \
      libigfxcmrt-dev
    

Security Pre-Configuration

  1. Network Segmentation:
    1
    2
    3
    4
    
    # Create VLAN for security cameras
    nmcli con add type vlan ifname cameras dev enp3s0 id 50
    nmcli con modify vlan-cameras ipv4.addresses 192.168.50.1/24
    nmcli con modify vlan-cameras ipv4.method manual
    
  2. Firewall Rules:
    1
    2
    3
    
    sudo ufw allow from 192.168.50.0/24 to any app Samba
    sudo ufw allow from 192.168.10.0/24 to any port 32400 proto tcp # Plex
    sudo uws deny in on cameras
    

Installation & Configuration

1. GPU Driver Installation (Intel Arc)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Add Intel repository
echo "deb [arch=amd64] https://repositories.intel.com/graphics/ubuntu jammy main" | \
  sudo tee /etc/apt/sources.list.d/intel-graphics.list

# Install dependencies
wget -qO - https://repositories.intel.com/graphics/intel-graphics.key | \
  sudo gpg --dearmor --output /usr/share/keyrings/intel-graphics.gpg

sudo apt update && sudo apt install -y \
  intel-i915-dkms \
  intel-platform-vsec-dkms \
  intel-platform-cse-dkms \
  intel-fw-gpu \
  intel-opencl-icd \
  intel-level-zero-gpu \
  oneapi-level-zero-devel

Verify GPU recognition:

1
sudo intel_gpu_top

2. Docker Configuration with Hardware Acceleration

Create /etc/docker/daemon.json:

1
2
3
4
5
6
7
8
9
10
11
12
{
  "runtimes": {
    "nvidia": {
      "path": "nvidia-container-runtime",
      "runtimeArgs": []
    }
  },
  "default-runtime": "nvidia",
  "features": {
    "gpu": "intel"
  }
}

Load necessary kernel modules:

1
2
sudo modprobe i915
sudo modprobe snd_hda_intel

3. Frigate NVR with Coral TPU

docker-compose.yml excerpt:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
services:
  frigate:
    image: ghcr.io/blakeblackshear/frigate:stable
    container_name: frigate
    restart: unless-stopped
    devices:
      - /dev/dri:/dev/dri # Intel GPU
      - /dev/bus/usb:/dev/bus/usb # Coral USB
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ./config.yml:/config/config.yml
      - /media/frigate:/media/frigate
    environment:
      FRIGATE_RTSP_PASSWORD: "${FRIGATE_PASSWORD}"
    deploy:
      resources:
        reservations:
          devices:
            - driver: intel
              count: 1
              capabilities: [gpu]
    networks:
      - cameras

config.yml highlights:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
mqtt:
  host: 192.168.10.5

detectors:
  coral:
    type: edgetpu
    device: pci

model:
  width: 320
  height: 320
  input_tensor: nhwc
  input_format: rgb

cameras:
  front_door:
    ffmpeg:
      inputs:
        - path: rtsp://admin:password@192.168.50.101:554/Streaming/Channels/101
          roles:
            - detect
    detect:
      width: 1280
      height: 720
      fps: 5

4. Plex Media Server Configuration

Optimized Docker deployment:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
services:
  plex:
    image: plexinc/pms-docker
    container_name: plex
    restart: unless-stopped
    network_mode: host
    environment:
      - PLEX_CLAIM=claim-xxxxxxxxxxxxx
      - PLEX_UID=1000
      - PLEX_GID=1000
      - NVIDIA_DRIVER_CAPABILITIES=all
    devices:
      - /dev/dri:/dev/dri
    volumes:
      - ./plex/config:/config
      - /media/storage/tv:/tv
      - /media/storage/movies:/movies

Enable hardware acceleration in Plex Settings:

1
Transcoder > Use hardware acceleration: Intel Quick Sync

5. ZFS Storage Configuration

Optimal pool creation:

1
2
3
4
5
6
7
8
9
sudo zpool create -f -o ashift=12 \
  -O compression=lz4 \
  -O acltype=posixacl \
  -O xattr=sa \
  -O atime=off \
  -O relatime=on \
  -O recordsize=1M \
  tank mirror /dev/disk/by-id/ata-WDC_WD120EFBX-68B0EN0_XXXXXX \
          mirror /dev/disk/by-id/ata-WDC_WD120EFBX-68B0EN0_XXXXXX

Tuning parameters:

1
2
3
sudo zfs set primarycache=metadata tank
sudo zfs set secondarycache=metadata tank
sudo zfs set dedup=off tank

Performance Optimization

GPU Workload Distribution

WorkloadAcceleration DevicePerformance Impact
Video TranscodingIntel QuickSync8x 1080p streams
AI InferenceCoral TPU30 FPS @ 1080p
3D RenderingIntel Arc GPUNot recommended

Frigate Tuning Parameters

Critical config.yml optimizations:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
detect:
  max_disappeared: 25
  stationary:
    interval: 0
    threshold: 50

objects:
  track:
    - person
    - car
  filters:
    person:
      min_area: 5000
      max_area: 100000
      threshold: 0.8

Plex Transcoding Profiles

Create custom profile at /config/Library/Application Support/Plex Media Server/Profiles/Advanced.xml:

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="utf-8"?>
<Profile>
  <TranscodeTargets>
    <VideoProfile protocol="hls" container="mpegts" codec="h264" />
    <VideoProfile protocol="dash" container="mp4" codec="h264" />
    <VideoProfile protocol="http" container="mkv" codec="h264" />
  </TranscodeTargets>
  <DirectPlayProfiles>
    <VideoProfile container="mkv" codec="hevc" />
    <VideoProfile container="mp4" codec="av1" />
  </DirectPlayProfiles>
</Profile>

ZFS ARC Tuning

Adjust cache allocation in /etc/modprobe.d/zfs.conf:

1
2
options zfs zfs_arc_max=4294967296  # 4GB limit
options zfs zfs_prefetch_disable=1  # Disable prefetch

Operational Management

Monitoring Stack

Recommended Prometheus exporters:

  1. Node Exporter: System metrics
  2. ZFS Exporter: Pool health monitoring
  3. NVIDIA DCGM Exporter: GPU metrics
  4. Frigate Exporter: Detection statistics

Sample Grafana dashboard configuration:

1
2
3
4
5
6
7
8
9
panels:
  - title: Transcoding Load
    targets:
      - expr: 100 * (rate(plex_transcode_sessions_active[5m]))
        legend: Transcode Utilization
  - title: Object Detection
    targets:
      - expr: frigate_detection_fps
        legend: ""

Backup Strategy

  1. Configuration Backup (Daily):
    1
    2
    3
    4
    5
    
    tar -czvf /backups/$(date +\%F).tar.gz \
      /etc/docker \
      /var/lib/docker/volumes \
      /etc/frigate \
      /etc/plex
    
  2. Media Backup (Weekly):
    1
    2
    
    zfs snapshot tank/media@$(date +\%F)
    zfs send tank/media@$(date +\%F) | ssh backup-host "zfs receive backup/media"
    
  3. Database Export (Plex/Frigate):
    1
    
    docker exec -t $CONTAINER_ID pg_dump -U postgres frigate > frigate-$(date +\%F).sql
    

Update Management

Safe update procedure:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 1. Stop containers gracefully
docker compose down

# 2. Update base system
sudo apt update && sudo apt upgrade -y

# 3. Update container images
docker compose pull

# 4. Rebuild with new images
docker compose up -d --force-recreate

# 5. Verify services
docker compose logs -f --tail=50

Troubleshooting Guide

Common Issues and Solutions

SymptomDiagnosisResolution
Coral TPU not detectedUSB enumeration failedecho 'SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", MODE="0660", GROUP="frigate"' > /etc/udev/rules.d/99-coral.rules
GPU acceleration unavailablePermission issuesAdd user to render and video groups: sudo usermod -aG render,video $USER
Frigate high latencyInsufficient TPU powerLimit detection FPS: detect: fps: 5 in config
Plex transcoding failuresIncorrect VAAPI setupVerify /dev/dri device mapping in Docker

Diagnostic Commands

Check GPU utilization:

1
sudo intel_gpu_top -l

Monitor Coral TPU:

1
2
sudo apt install edgetpu-utils
edgetpu_classify --device any

Inspect Docker GPU access:

1
docker run --rm -it --gpus all ubuntu nvidia-smi

Log Analysis Techniques

  1. Frigate Event Debugging:
    1
    
    docker logs $CONTAINER_ID frigate | grep -E 'detection|ffmpeg'
    
  2. Plex Transcoding Issues:
    1
    
    grep -i "transcode" "/path/to/Plex Media Server/Logs/Plex Transcoder.log"
    
  3. ZFS Performance Problems:
    1
    
    zpool iostat -
    
This post is licensed under CC BY 4.0 by the author.