Homelab System Architecture
Detailed architectural overview, hardware specifications, networking topology, and resource allocation strategies for the self-hosted homelab.
1. System Topology & Interconnect
flowchart TD
subgraph Clients ["📱 Client Devices (Encrypted Mesh)"]
Phone["📱 Mobile Client\n(Tailscale)"]
Laptop["💻 Laptop\n(Tailscale)"]
EReader["📖 E-Reader\n(KOReader)"]
Discord["🤖 Discord App\n(Mobile Widget)"]
Telegram["🔒 Telegram App\n(Encrypted Bot)"]
end
subgraph NetworkMesh ["🔐 Network Ingress"]
TailscaleMesh["Tailscale WireGuard Mesh\n(MagicDNS: 'homelab')"]
end
subgraph Host ["🖥️ HP ProDesk Server (Core 24/7 Stack)"]
subgraph MediaServices ["Core Media Services"]
ImmichWeb["Immich Photos\n(:2283)"]
Navi["Navidrome Music\n(:4533)"]
ABS["Audiobookshelf\n(:13378)"]
Calibre["Calibre-Web\n(:8083)"]
end
subgraph DatabaseLayer ["Internal Databases & Sidecars"]
Postgres[("Immich PostgreSQL 14\nVectorChord + pgvector")]
Valkey[("Immich Valkey Cache")]
ImmichML["Immich ML Sidecar\n(Profile: 'ml', On-Demand)"]
end
subgraph Ingestion ["Mobile Ingestion Pipeline"]
DiscordBot["Discord Bot\n(Stealth Emoji)"]
TelegramBot["Telegram Bot\n(AES-256 Crypto)"]
PipelineEngine["Pipeline Engine\n(yt-dlp + mutagen)"]
end
subgraph StorageSubsystem ["💾 Storage Subsystem"]
AppData["SSD: /srv/docker\n(Databases, Configs, ML Models)"]
MediaStorage["Bulk Storage: /srv/storage/media\n(Music, Books, Audiobooks, Photos)"]
DownloadsStorage["Bulk Storage: /srv/storage/downloads\n(Drop-Chute & Scratch)"]
RestrictedStorage["Bulk Storage: /srv/storage/restricted\n(Private & Sensitive Media)"]
end
end
%% Client Ingress
Phone -->|WireGuard| TailscaleMesh
Laptop -->|WireGuard| TailscaleMesh
EReader -->|OPDS| Calibre
TailscaleMesh --> MediaServices
%% Bot Ingestion
Discord -->|Links & Files| DiscordBot
Telegram -->|Restricted Links| TelegramBot
DiscordBot --> PipelineEngine
TelegramBot --> PipelineEngine
%% Database & ML Connections
ImmichWeb --> Postgres
ImmichWeb --> Valkey
ImmichWeb -.->|Batch Ingest| ImmichML
%% Storage Volume Handoffs
MediaServices --> AppData
MediaServices --> MediaStorage
PipelineEngine --> DownloadsStorage
PipelineEngine --> MediaStorage
PipelineEngine --> RestrictedStorage
2. Hardware Context & Constraints
- Host Platform: HP ProDesk 400/600/800 G6 Microtower / SFF
- CPU: Intel Core i5-10400 (6 Cores, 12 Threads, 2.90 GHz base, 4.30 GHz turbo, Intel UHD Graphics 630 with QuickSync)
- RAM: 32 GB Dual-Channel DDR4 (2x 16GB Micron DDR4-3200 1Rx8
MTA8ATF2G64AZ, configured for high headroom: ~1.3 GB idle stack leaves >30.5 GB for OS caching, ZFS/Btrfs, local LLMs/Ollama, and active workloads) - Storage Subsystem:
- OS & Appdata Drive (SSD Permanently): High-speed NVMe SSD hosting
/and persistent container state (/srv/docker/). SQLite and PostgreSQL databases thrive on SSD 4K random I/O. - Bulk Media Storage (
/srv/storage/): High-capacity storage hosting media libraries (/srv/storage/media/), staging drop-chutes (/srv/storage/downloads/), and private content (/srv/storage/restricted/). Starts on SSD, designed to migrate cleanly to a dedicated bulk HDD without changing Docker configs.
3. Network Architecture (Tailscale Mesh)
- Zero Open Ports: No public port-forwarding or dynamic DNS exposed to the public internet.
- Mesh Connectivity: All connections occur over an encrypted WireGuard mesh via Tailscale.
- MagicDNS: Devices reach services using friendly DNS names (e.g.,
http://homelab:2283,http://homelab:4533). - Mobile Access: Mobile phones access media and streaming directly through the Tailscale mobile client.
- E-Reader Sync: E-ink devices running KOReader connect to Calibre-Web's OPDS catalog over Tailscale.
4. Storage Architecture & Directory Schema
The storage layout cleanly separates high-IOPS transactional state (SSD) from bulk sequential media streams (HDD-migration ready). Placing media/ and downloads/ on the same filesystem root (/srv/storage) ensures all intake operations occur via instant, atomic zero-copy inode moves.
Persistent Bulk Storage (/srv/storage/)
Starts on SSD, moves cleanly to HDD later:
/srv/storage/
├── media/
│ ├── music/ # FLAC, MP3, and Opus files (Navidrome)
│ ├── audiobooks/ # Audiobook files organized by Author/Title (Audiobookshelf)
│ ├── podcasts/ # Downloaded and subscribed podcasts (Audiobookshelf)
│ ├── books/ # EPUB, PDF, and MOBI library (Calibre-Web)
│ ├── video/ # Video archives & Jellyfin library
│ └── photos/ # Raw and encoded photos & videos (Immich uploads)
│
├── downloads/ # Atomic staging & ingestion chute
│ ├── intake/ # Drop folder monitored by `make watch`
│ │ ├── music/
│ │ ├── audiobooks/
│ │ ├── books/
│ │ └── video/
│ └── scratch/ # yt-dlp transcoding and assembly working directory
│
└── restricted/ # Isolated partition for private/restricted downloads (Telegram bot)
Application Data & Container State (/srv/docker/)
Databases, runtime configs, and model weights (strictly .gitignored, stays on SSD):
/srv/docker/
├── audiobookshelf/
│ ├── config/ # ABS configuration
│ └── metadata/ # Scraped metadata cache & SQLite state
├── calibre-web/ # User preferences and app settings
├── navidrome/ # Navidrome SQLite database (navidrome.db)
├── immich/
│ ├── postgres/ # PostgreSQL 14 cluster data & VectorChord indexes
│ └── model-cache/ # CLIP and facial recognition models
├── jellyfin/ # Transcode cache & server config (Phase 6)
├── ollama/ # Local LLM model weights (fast NVMe retrieval)
└── portainer/ # Container management agent data
5. Zero-Idle Performance Verification
During laptop benchmark testing (September 26, 2026), the entire 24/7 core stack yielded the following live resource measurements:
| Container | Idle CPU | Measured Idle RAM | Peak Under Load | Strategy |
|---|---|---|---|---|
navidrome |
0.03% | 13.8 MB | ~200 MB | 24/7 background daemon |
immich-valkey |
0.37% | 5.3 MB | ~80 MB | 24/7 background daemon |
audiobookshelf |
0.06% | 36.2 MB | ~500 MB | 24/7 background daemon |
calibre-web |
0.02% | 187.8 MB | ~300 MB | 24/7 background daemon |
immich-postgres |
0.00% | 399.4 MB | ~1.0 GB | 24/7 background daemon |
immich-server |
0.17% | 697.2 MB | ~1.2 GB | 24/7 background daemon |
| Combined Core | 0.65% | ~1.33 GB | ~3.2 GB | Zero-idle verified |
immich-machine-learning |
0.00% | 0 MB (Stopped) | ~1.5 - 3.5 GB | Profile ml (isolated) |