Self-hosted infrastructure powering 40+ containerized services with 33TB of ZFS-backed storage.
  • PHP 47.4%
  • TypeScript 36.4%
  • Python 5.2%
  • HTML 4.6%
  • Hack 2.9%
  • Other 3.5%
Find a file
2026-05-14 08:10:50 +02:00
.github/workflows security: sanitize remaining hardcoded credentials, remove legacy tree, add secret scanning 2026-05-07 05:16:19 +02:00
docs docs: index HA guide and fill missing file entries across all indexes 2026-05-14 08:10:50 +02:00
infrastructure docs: index HA guide and fill missing file entries across all indexes 2026-05-14 08:10:50 +02:00
scripts Complete restructuring 2026-02-28 15:31:40 +01:00
services security: sanitize remaining hardcoded credentials, remove legacy tree, add secret scanning 2026-05-07 05:16:19 +02:00
.env.example security: sanitize remaining hardcoded credentials, remove legacy tree, add secret scanning 2026-05-07 05:16:19 +02:00
.gitignore add: Pangolin-HA-Setup-Guide 2026-05-13 03:05:10 +02:00
.gitleaks.toml security: sanitize remaining hardcoded credentials, remove legacy tree, add secret scanning 2026-05-07 05:16:19 +02:00
INDEX.md docs: index HA guide and fill missing file entries across all indexes 2026-05-14 08:10:50 +02:00
README.md docs: index HA guide and fill missing file entries across all indexes 2026-05-14 08:10:50 +02:00

Homelab Infrastructure

Status Services Storage OS NAS

A reference implementation of a self-hosted home infrastructure stack: 60+ self-hosted services across 100+ containers, 33 TB storage, zero port-forwarding. Runs on NixOS with DPlaneOS, 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

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)     100+ 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
FlareSolverr Cloudflare bypass for indexers arr-suite.yml
Recyclarr TRaSH Guides quality profile sync arr-suite.yml
Maintainerr Media library cleanup rules arr-suite.yml
Seerr Media request management arr-suite.yml
qBittorrent Download client (via Gluetun VPN) arr-suite.yml
Gluetun WireGuard VPN gateway for downloads arr-suite.yml
Audiobookshelf Audiobooks + podcast server books.yml
Grimmory Ebook library (Booklore-based, MariaDB) books.yml
Bookkeep Book discovery and request manager books.yml
Readmeabook Audiobook request manager books.yml
SwingMusic Self-hosted music player swingmusic.yml
Navidrome Music streaming (Subsonic API) navidrome.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
CryptPad End-to-end encrypted collaborative office cryptpad.yml
TriliumNext Notes Hierarchical personal knowledge base trilium.yml
Glass Keep Lightweight notes app glass-keep.yml
Librum Self-hosted ebook reading and library librum.yml
BentoPDF PDF tools web app bentopdf.yml
Revolt.chat Self-hosted Discord alternative revolt.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
Newt Pangolin tunnel client newt.yml
Tailscale DERP Self-hosted Tailscale relay server tailscale-derper.yml
Traefik v3 Reverse proxy, TLS termination VPS-managed - see infrastructure/networking/traefik/
Pangolin + Gerbil Self-hosted Cloudflare Tunnel VPS + Pi - see infrastructure/networking/pangolin/
CrowdSec IDS/IPS, collaborative threat intel VPS-managed - see infrastructure/security/crowdsec/
MinIO S3-compatible local object storage minio.yml
Beszel Lightweight server resource monitoring hub beszel.yml
Beszel Agent Per-host metrics collector beszel-agent.yml
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
Homarr Service dashboard homarr.yml
Kasm Containerized browser/desktop streaming kasm.yml
Heaper Docker host resource and container manager heaper.yml
Arcane Docker management UI arcane.yml
Syncthing Peer-to-peer file sync (config backup) syncthing.yml
SearXNG Self-hosted metasearch engine searxng.yml
Zelest Stacks Compose stack management UI stacks.yml
PostgreSQL (×8) Relational database instances Per-service
Redis (×3) In-memory cache instances Per-service

Development

Service Purpose Location
DPlaneOS website Project landing page (nginx static) d-planeos-website.yml
Dan Portfolio Personal portfolio site (PHP + Postfix relay) dan-portfolio.yml
Forgejo Self-hosted Git forge forgejo.yml
Nginx CV Personal CV/resume web page nginx-cv.yml
Resume Builder Next.js frontend + FastAPI backend + AI-powered PDF resume parser resume-builder.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 DPlaneOS.

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 DPlaneOS'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 DPlaneOS. 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
│   │   ├── newt/newt.yml
│   │   ├── tailscale-derper/tailscale-derper.yml
│   │   ├── traefik/          # Traefik config notes (VPS-managed)
│   │   └── pangolin/
│   │       ├── README.md                    # Tunnel docs + component map
│   │       └── terraform/                   # Infrastructure as Code
│   │           ├── main.tf / cloudflare.tf / vps.tf / backend.tf / variables.tf
│   │           ├── docker-compose.yml        # Pangolin stack (deployed to VPS)
│   │           ├── config/                   # Pangolin + Traefik configs
│   │           ├── scripts/backup.sh         # Weekly backup → MinIO
│   │           ├── scripts/restore.sh        # DR restore from MinIO
│   │           ├── minio/docker-compose.yml  # MinIO on NAS (Dockge)
│   │           ├── pangolin-terraform-iac.md # IaC documentation
│   │           └── DR_RUNBOOK.md             # Disaster recovery procedure
│   ├── security/
│   │   ├── vaultwarden/vaultwarden.yml
│   │   └── crowdsec/         # CrowdSec notes (VPS-managed)
│   ├── monitoring/
│   │   ├── beszel/beszel.yml
│   │   ├── beszel-agent/beszel-agent.yml
│   │   ├── big-bear-scrutiny/scrutiny.yml
│   │   ├── big-bear-dockge/dockge.yml
│   │   ├── big-bear-dockpeek/dockpeek.yml
│   │   └── glances-dashboard.yml
│   └── storage/
│       ├── minio/minio.yml
│       └── README.md
├── services/
│   ├── media/
│   │   ├── arr-suite.yml              # Emby, Sonarr, Radarr, Lidarr, Prowlarr, Bazarr, qBittorrent, Gluetun, Seerr, Maintainerr
│   │   ├── books/books.yml            # Audiobookshelf, Grimmory, Bookkeep, Readmeabook
│   │   ├── immich/immich.yml
│   │   ├── navidrome/navidrome.yml
│   │   ├── pinchflat/pinchflat.yml
│   │   ├── stremio/stremio.yml
│   │   └── swingmusic/swingmusic.yml
│   ├── productivity/
│   │   ├── nextcloud.yml              # Nextcloud, Collabora, Talk HPB, Redis, PostgreSQL
│   │   ├── bentopdf/bentopdf.yml
│   │   ├── cryptpad/cryptpad.yml
│   │   ├── glass-keep/glass-keep.yml
│   │   ├── librum/librum.yml
│   │   ├── revolt/revolt.yml
│   │   ├── trilium/trilium.yml
│   │   ├── 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/
│   │   ├── homarr/homarr.yml
│   │   ├── kasm/kasm.yml
│   │   ├── heaper/heaper.yml
│   │   ├── arcane/arcane.yml
│   │   ├── stacks.yml
│   │   ├── syncthing/syncthing.yml
│   │   └── searxng/searxng.yml
│   └── development/
│       ├── d-planeos-website.yml
│       ├── dan-portfolio/dan-portfolio.yml
│       ├── forgejo/forgejo.yml
│       ├── nginx-cv/nginx-cv.yml
│       └── resume-builder.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
│   ├── nextcloud-update-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 DPlaneOS (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 Cloudflare Tunnel
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 DPlaneOS ZimaOS limitations, alternatives considered, what DPlaneOS 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
Pangolin HA Setup Active-passive failover: Litestream B2 replication, Cloudflare DNS flip, ~7-8 min RTO
Media Stack Arr suite + Emby configuration
Productivity Services Nextcloud, Immich, Paperless setup
Nextcloud Optimisation PostgreSQL + Redis + PHP tuning
Nextcloud Update Guide Post-update occ commands, failure diagnosis, 502 behind Traefik
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

Pangolin

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.


🗄️ DPlaneOS - the NAS management layer (self-developed)

DPlaneOS

A NAS management layer I built myself - ZFS pool management, SMB/NFS shares, Docker orchestration, and a unified web UI, purpose-built on top of NixOS. Developed as a high-performance Go daemon to fill the gap between CasaOS (simple but limited) and TrueNAS (powerful but container-hostile).


🐳 Core infrastructure

Project Role in this stack
NixOS The OS everything runs on. Declarative system configuration, atomic rollbacks, reproducible builds - the base that makes the whole stack manageable. DPlaneOS runs on top of it.
Traefik Reverse proxy - TLS termination, automatic Let's Encrypt, routing. Runs on the VPS and handles every inbound HTTPS request.
CrowdSec 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.
Pi-hole Network-wide DNS and ad-blocking. Every device on the LAN benefits without any per-device configuration.
OpenZFS 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
Nextcloud Google Drive, Google Docs, iCloud
Immich Google Photos
Vaultwarden 1Password, LastPass
Paperless-NGX Manual document filing
Emby Netflix, Plex (self-hosted media server)
Sonarr Radarr Lidarr Manual media management
Prowlarr Per-client indexer configuration
Bazarr Manual subtitle hunting
Gluetun Any VPN client - containerised, provider-agnostic WireGuard gateway
Syncthing Dropbox, rsync scripts
Dockge Manual docker compose commands
Scrutiny Ignoring disk health until something fails
SearXNG Google, Bing
Audiobookshelf Audible, podcast apps
Navidrome Spotify (self-hosted music streaming)
SwingMusic Local music player apps
Pinchflat YouTube Premium downloads
Linkwarden Browser bookmarks, Pocket
Memos Notion, Apple Notes
Wallos Manual subscription tracking
Glances Scattered system monitoring tools
Joplin Evernote, Apple Notes (sync backend)

DPlaneOS Pangolin