- PHP 48.5%
- TypeScript 37.3%
- Python 5.3%
- HTML 4.8%
- Hack 3%
- Other 1.1%
|
|
||
|---|---|---|
| docker | ||
| docs | ||
| infrastructure | ||
| scripts | ||
| services | ||
| .env.example | ||
| .gitignore | ||
| INDEX.md | ||
| README.md | ||
Homelab Infrastructure
A reference implementation of a self-hosted home infrastructure stack: 40+ containerised services, 33 TB storage, zero port-forwarding. Runs on NixOS with D-PlaneOS — a self-developed NAS management layer — currently migrating storage from BTRFS RAID5 to ZFS RAID-Z2.
INDEX.md — complete map of every file in this repository.
Contents
- Architecture
- Security model
- Service matrix
- Storage strategy
- Repository structure
- Tech stack
- Cost analysis
- Documentation
- Quick start
Architecture
Internet
│
▼
VPS — IONOS, Berlin (2 vCPU / 2 GB RAM / 80 GB NVMe)
├─ UFW firewall ports 80, 443, 51820 only
├─ CrowdSec IDS/IPS community blocklists, Traefik bouncer
├─ Traefik v3 TLS 1.3 termination, Let's Encrypt
└─ Gerbil WireGuard endpoint (Pangolin component)
│
│ WireGuard tunnel — ChaCha20-Poly1305, encrypted
▼
Raspberry Pi 5 — local LAN hub (Pangolin brain)
├─ Pangolin server identity, routing control plane
├─ Newt tunnel termination
└─ Traefik (inner) internal routing → services
│
▼
Home network — 10.XXX.0.0/24
├─ NAS server (10.XXX.0.1) 40+ containers, 33 TB storage
└─ Pi-hole (10.XXX.0.2) DNS, ad-blocking
Key design decision: Pangolin tunnel instead of port-forwarding means the home IP is never exposed, there is no dynamic DNS dependency, and the home router attack surface is zero.
Interactive diagrams: Architecture · Security layers · Data flow
Security model
Defense in depth: each layer is independently hardened and does not rely on the correctness of outer layers.
Layer 1 — Perimeter (VPS)
UFW: only ports 80, 443, 51820 reachable from internet
CrowdSec: IP reputation, automated banning, community threat feeds
DDoS mitigation: IONOS network-level
Layer 2 — Transport
WireGuard: encrypted tunnel between VPS and home network
TLS 1.3: enforced at both outer (VPS Traefik) and inner (Pi Traefik) layers
Let's Encrypt: certificates auto-renewed, HSTS enabled
Layer 3 — Network isolation
Docker bridge networks scoped per service group
Databases not exposed to host network interface
Services communicate only via explicitly defined networks
Layer 4 — Application
Per-service authentication; OIDC where supported
2FA enforced on Vaultwarden and Nextcloud
Vaultwarden for shared credential management
Layer 5 — Data integrity
ZFS end-to-end checksumming: every block verified on read, silent corruption repaired from RAID-Z2 parity
RAID-Z2: dual-disk fault tolerance, no write-hole vulnerability (unlike BTRFS RAID5)
Scheduled scrubs verify the full pool
Current: migrating from BTRFS RAID5 — see infrastructure/storage/README.md
Service matrix
Media
| Service | Purpose | Compose |
|---|---|---|
| Emby | Media server | arr-suite.yml |
| Sonarr | TV show automation | arr-suite.yml |
| Radarr | Movie automation | arr-suite.yml |
| Lidarr | Music automation | arr-suite.yml |
| Prowlarr | Indexer management | arr-suite.yml |
| Bazarr | Subtitle automation | arr-suite.yml |
| qBittorrent | Download client (via Gluetun VPN) | arr-suite.yml |
| Gluetun | WireGuard VPN gateway for downloads | arr-suite.yml |
| SwingMusic | Self-hosted music player | swingmusic.yml |
| Navidrome | Music streaming (Subsonic API) | navidrome.yml |
| Audiobookshelf | Audiobooks + podcast server | audiobookshelf.yml |
| Pinchflat | YouTube archiver | pinchflat.yml |
| Stremio Server | Streaming add-on server | stremio.yml |
Productivity & cloud
| Service | Purpose | Compose |
|---|---|---|
| Nextcloud + Collabora | File sync, cloud office suite | nextcloud.yml |
| Nextcloud Talk HPB | High-performance video call backend | nextcloud.yml |
| Immich | Google Photos replacement | immich.yml |
| Paperless-NGX | Document OCR and archive | paperless.yml |
| Vaultwarden | Self-hosted Bitwarden server | vaultwarden.yml |
| Joplin Server | Note sync backend | joplin.yml |
| Memos | Lightweight notes / journal | memos.yml |
| Linkwarden | Bookmark archiver with full-page capture | linkwarden.yml |
| Wallos | Subscription and expense tracker | wallos.yml |
Infrastructure & management
| Service | Purpose | Compose |
|---|---|---|
| Pi-hole | Network-wide DNS + ad-blocking | pihole.yml |
| Traefik v3 | Reverse proxy, TLS termination | VPS-managed — see infrastructure/networking/traefik/ |
| Pangolin + Gerbil | Self-hosted WireGuard tunnel | VPS + Pi — see infrastructure/networking/pangolin/ |
| CrowdSec | IDS/IPS, collaborative threat intel | VPS-managed — see infrastructure/security/crowdsec/ |
| Dockge | Docker Compose management UI | dockge.yml |
| Dockpeek | Container health dashboard | dockpeek.yml |
| Scrutiny | S.M.A.R.T disk health monitoring | scrutiny.yml |
| Glances | System resource monitoring | glances-dashboard.yml |
| Syncthing | Peer-to-peer file sync (config backup) | syncthing.yml |
| SearXNG | Self-hosted metasearch engine | searxng.yml |
| PostgreSQL (×8) | Relational database instances | Per-service |
| Redis (×3) | In-memory cache instances | Per-service |
Development
| Service | Purpose | Location |
|---|---|---|
| D-PlaneOS website | Project landing page | d-planeos-website.yml |
| Aptifolio | Next.js frontend + FastAPI backend + PDF resume parser | aptifolio.yml |
Storage strategy
Full details: infrastructure/storage/README.md
33 TB across four HDDs — currently BTRFS on mdadm RAID5 (legacy, from ZimaOS). Migrating to ZFS RAID-Z2 via D-PlaneOS.
Why ZFS
ZFS RAID-Z2 (dual-parity) eliminates the write-hole vulnerability present in BTRFS RAID5, provides end-to-end checksumming at every level of the storage tree, and integrates cleanly with D-PlaneOS's pool and dataset management. zfs send replication makes off-site backup straightforward. The 15+ year production track record in enterprise environments makes it the right choice for a long-lived NAS.
Target pool layout
zpool: mainpool (RAID-Z2, 4× HDD)
├── mainpool/appdata /DATA/AppData — container bind-mount volumes
├── mainpool/media /DATA/Media — media library
├── mainpool/home user home directories
└── mainpool/backups local snapshot targets
zpool: bootpool (mirror, NVMe)
└── NixOS system root
Pool and dataset configuration is managed through D-PlaneOS. Refer to that repository for NixOS module definitions and dataset property details (compression=zstd, xattr=sa, recordsize tuning per workload).
Repository structure
homelab/
├── infrastructure/
│ ├── networking/
│ │ ├── pihole/pihole.yml
│ │ ├── traefik/ # Traefik config notes (VPS-managed)
│ │ └── pangolin/ # Pangolin tunnel docs + component map
│ ├── security/
│ │ ├── vaultwarden/vaultwarden.yml
│ │ └── crowdsec/ # CrowdSec notes (VPS-managed)
│ ├── monitoring/
│ │ ├── big-bear-scrutiny/scrutiny.yml
│ │ ├── big-bear-dockge/dockge.yml
│ │ ├── big-bear-dockpeek/dockpeek.yml
│ │ └── glances-dashboard.yml
│ └── storage/
│ └── README.md
├── services/
│ ├── media/
│ │ ├── arr-suite.yml # Sonarr, Radarr, Lidarr, Prowlarr, Bazarr, qBittorrent, Gluetun
│ │ ├── audiobookshelf/audiobookshelf.yml
│ │ ├── immich/immich.yml
│ │ ├── navidrome/navidrome.yml
│ │ ├── pinchflat/pinchflat.yml
│ │ ├── stremio/stremio.yml
│ │ └── swingmusic/swingmusic.yml
│ ├── productivity/
│ │ ├── nextcloud.yml # Nextcloud, Collabora, Talk HPB, Redis, PostgreSQL
│ │ ├── big-bear-joplin/joplin.yml
│ │ ├── big-bear-linkwarden/linkwarden.yml
│ │ ├── big-bear-paperless-ngx/paperless.yml
│ │ ├── big-bear-wallos/wallos.yml
│ │ └── memos/memos.yml
│ ├── management/
│ │ ├── stacks.yml
│ │ ├── syncthing/syncthing.yml
│ │ └── searxng/searxng.yml
│ └── development/
│ ├── d-planeos-website.yml
│ ├── aptifolio.yml
│ └── aptifolio-dockge.yml
├── scripts/
│ └── export-all-compose.sh
├── docs/
│ ├── hardware-specs.md
│ ├── homelab-complete-journey.md
│ ├── docker-infrastructure.md
│ ├── network-security.md
│ ├── network-remote-access.md
│ ├── media-stack.md
│ ├── productivity-services.md
│ ├── nextcloud-optimization-guide.md
│ ├── homelab-dashboard-guide.md
│ ├── pangolin-infrastructure.md
│ ├── pangolin-deployment-guide.md
│ ├── pangolin-configurations.md
│ ├── pangolin-vps-relay-guide.md
│ ├── pangolin-upgrade-guide.md
│ ├── pangolin-z-performance-tuning.md
│ ├── pangolin-traefikdashboard-guide.md
│ ├── NIXOS-MIGRATION.md
│ ├── DOCKER-SERVICES.md
│ ├── INDEX.md
│ └── *.html # Interactive architecture diagrams
├── docker/ # Legacy source tree — see docker/README.md
├── .env.example # All required environment variables
└── README.md
Tech stack
| Layer | Technology |
|---|---|
| Operating system | NixOS — declarative, reproducible, atomic OTA |
| NAS management | D-PlaneOS (self-developed) — ZFS pool management, SMB/NFS, Docker orchestration, web UI |
| Container orchestration | Docker Compose |
| Reverse proxy | Traefik v3 — TLS 1.3, automatic Let's Encrypt |
| Tunnel | Pangolin — self-hosted WireGuard |
| Security | CrowdSec IDS/IPS |
| DNS | Pi-hole |
| Storage | OpenZFS RAID-Z2 (target) — migrating from BTRFS on mdadm RAID5 — 33 TB |
| Databases | PostgreSQL 14 (×8 instances), Redis Alpine (×3 instances) |
| Hardware | Intel i3-13100 / 32 GB DDR4-3200 / 120 GB NVMe |
| VPS gateway | IONOS Berlin — 2 vCPU / 2 GB / 80 GB NVMe |
Cost analysis
Initial investment
Hardware €1,290
VPS (3 yr) €180
Domain (3 yr) €36
────────────────────────────
Total €1,506
Annual operating cost
Electricity €75 (~30 W average, €0.30/kWh)
VPS €60
Domain €12
────────────────────────────
Total €147/yr (€12/month)
Replaced SaaS (annual)
Google One €30
Dropbox Plus €120
1Password €60
Spotify €180
Netflix €156
iCloud+ €36
────────────────────────────
Total replaced €582/yr
Net savings: €435/yr → break-even Year 4
Documentation
| Document | Description |
|---|---|
| Why D-PlaneOS | ZimaOS limitations, alternatives considered, what D-PlaneOS solves |
| Complete Journey | Full build narrative, decisions, and lessons learned |
| Hardware Specs | Component list, benchmarks, power draw |
| Docker Infrastructure | Container architecture and patterns |
| Network Security | Security layer detail |
| Remote Access | VPN comparison, Pangolin vs Tailscale vs ZeroTier |
| Pangolin Infrastructure | Tunnel architecture deep-dive |
| Pangolin Deployment Guide | Step-by-step VPS setup |
| Pangolin Configurations | Config file reference |
| Pangolin VPS Relay | Relay server setup |
| Pangolin Upgrade Guide | Version upgrade procedures |
| Pangolin Performance Tuning | Kernel sysctl optimisations |
| Pangolin Traefik Dashboard | Dashboard configuration |
| Media Stack | Arr suite + Emby configuration |
| Productivity Services | Nextcloud, Immich, Paperless setup |
| Nextcloud Optimisation | PostgreSQL + Redis + PHP tuning |
| Dashboard Guide | Homelab dashboard setup |
| NixOS Migration Plan | ZimaOS → NixOS migration roadmap |
| Service Index | Full service inventory |
Quick start
# Clone
git clone https://github.com/4nonX/homelab
# Set up environment variables
cp .env.example .env
$EDITOR .env # fill in domains, passwords, IPs
# Deploy a stack — example: Nextcloud
cd services/productivity
docker compose -f nextcloud.yml up -d
# Deploy monitoring
cd infrastructure/monitoring
docker compose -f glances-dashboard.yml up -d
For the full external access setup (Pangolin tunnel + Traefik + CrowdSec on VPS), start with docs/pangolin-deployment-guide.md.
Built on the shoulders of giants
This homelab would not exist without these projects. Each one is worth knowing about.
🥇 Pangolin — the backbone of external access
The single most impactful piece of infrastructure in this stack. Pangolin is a self-hosted tunnelled reverse proxy with identity and access management — think Cloudflare Tunnel, but open source and entirely under your control.
Before Pangolin, the realistic options for external access were: open ports on your home router (bad), pay for a commercial tunnel (fine but a dependency), or set up WireGuard manually and manage it yourself (works, but significant operational overhead). Pangolin wraps WireGuard, Traefik, and an identity layer into something you can actually run on a cheap VPS and forget about. Zero port-forwarding. Zero home IP exposure. Let's Encrypt certificates handled automatically. The security architecture of this entire homelab is built around what Pangolin makes possible.
Components: Pangolin (control plane) · Gerbil (WireGuard gateway) · Newt (tunnel client) · Badger (identity)
If you self-host anything that needs external access, start here.
🗄️ D-PlaneOS — the NAS management layer (self-developed)
A NAS management layer I built myself — ZFS pool management, SMB/NFS shares, Docker orchestration, user management, and a unified web UI, purpose-built on top of NixOS. Developed specifically to fill the gap between CasaOS (simple but limited) and TrueNAS (powerful but container-hostile). The homelab you're looking at is its production testing environment. See docs/why-d-planeos.md.
🐳 Core infrastructure
| Project | Role in this stack |
|---|---|
| The OS everything runs on. Declarative system configuration, atomic rollbacks, reproducible builds — the base that makes the whole stack manageable. D-PlaneOS runs on top of it. | |
| Reverse proxy — TLS termination, automatic Let's Encrypt, routing. Runs on the VPS and handles every inbound HTTPS request. | |
| Collaborative IDS/IPS. Analyses Traefik logs, bans malicious IPs via bouncer, pulls community threat feeds. The passive security layer that works without any configuration after setup. | |
| Network-wide DNS and ad-blocking. Every device on the LAN benefits without any per-device configuration. | |
The filesystem everything is migrating to. End-to-end checksumming, RAID-Z2, snapshots, zfs send replication — the right foundation for a long-lived NAS. |
📦 Services
| Project | What it replaces |
|---|---|
| Google Drive, Google Docs, iCloud | |
| Google Photos | |
| 1Password, LastPass | |
| Manual document filing | |
| Netflix, Plex (self-hosted media server) | |
| Manual media management | |
| Per-client indexer configuration | |
| Manual subtitle hunting | |
| Any VPN client — containerised, provider-agnostic WireGuard gateway | |
| Dropbox, rsync scripts | |
Manual docker compose commands |
|
| Ignoring disk health until something fails | |
| Google, Bing | |
| Audible, podcast apps | |
| Spotify (self-hosted music streaming) | |
| Local music player apps | |
| YouTube Premium downloads | |
| Browser bookmarks, Pocket | |
| Notion, Apple Notes | |
| Manual subscription tracking | |
| Scattered system monitoring tools | |
| Evernote, Apple Notes (sync backend) |