docs: add full homelab documentation structure

This commit is contained in:
Paccoco
2026-05-05 14:43:09 -05:00
parent ee8a412a69
commit 370998b8d5
20 changed files with 1405 additions and 24 deletions

View File

@@ -0,0 +1,107 @@
# Homelab Architecture Overview
## Primary Docker Host
Host: `PlausibleDeniability` (TrueNAS Scale)
Production Docker workloads run on PlausibleDeniability via standalone Docker Compose stacks.
TrueNAS Apps (ix-app format) have been fully migrated to compose stacks.
## Repository Layout
Repo root: `/mnt/docker-ssd/docker/compose`
Remote: `git@github.com:Paccoco/truenas-stacks.git`
Gitea mirror: `https://gitea.paccoco.com/fizzlepoof/truenas-stacks.git`
Stack directories:
- `databases/` = shared-postgres, shared-mariadb, shared-redis — deploy FIRST
- `infrastructure/` = newt, homepage, uptime-kuma, dockhand, netdata, tailscale — deploy SECOND
- `media/` = plex, tautulli, audiobookshelf, seerr, calibre-web-automated
- `photos/` = immich server + machine learning
- `home/` = kitchenowl, donetick, dakboard bridge, shlink, shlink-web-client, qui
- `dev/` = gitea, rackpeek
- `ai/` = ollama, openwebui
- `meshtastic/` = meshmonitor, mqtt-proxy, tileserver, meshtastic-map
## Storage Model
### Local SSD
Mounted at: `/mnt/docker-ssd`
- Docker data root: `/mnt/docker-ssd/docker/docker-data`
- Databases: `/mnt/docker-ssd/docker/databases/`
- Write-heavy appdata: `/mnt/docker-ssd/docker/appdata/`
- GPU/model storage
- Apps that perform chown or aggressive startup writes
- SQLite-backed apps
Notable appdata on SSD:
- plex, tautulli, audiobookshelf, seerr, dockhand, rackpeek
- immich, immich-ml, ollama, openwebui
- shlink, gitea, netdata, tailscale, uptime-kuma
### TrueNAS Pool (tank)
Mounted at: `/mnt/tank`
- General appdata: `/mnt/tank/docker/appdata/`
- Backups: `/mnt/tank/docker/backups/`
- Downloads: `/mnt/tank/docker/downloads/`
Notable appdata on tank:
- homepage, newt, dockhand (config only)
- kitchenowl, donetick, qui
- calibre-web-automated config
### Unraid NFS
Mounted at: `/mnt/unraid`
- Media libraries: `/mnt/unraid/data/media/`
- Immich media: `/mnt/unraid/immich`
## Networks
- `ix-databases_shared-databases` — created by databases stack; project name `ix-databases` set in compose
- `pangolin` — created by newt at runtime; used by all externally exposed services
## Active Stacks (as of 2026-05-05)
### databases/
- shared-postgres (immich-optimized image with vectorchord + pgvector)
- shared-mariadb
- shared-redis
### infrastructure/
- newt, homepage, dockhand, uptime-kuma, netdata, tailscale
### media/
- ix-plex-plex-1 (GPU passthrough, RTX 2080 Ti)
- ix-tautulli-tautulli-1
- ix-audiobookshelf-audiobookshelf-1
- seerr (Postgres backend)
- calibre-web-automated
### photos/
- ix-immich-immich-server-1
- ix-immich-immich-machine-learning-1 (GPU, CUDA)
### home/
- kitchenowl, donetick, donetick-dakboard-bridge, qui, shlink, shlink-web-client
### dev/
- gitea, ix-rackpeek-rackpeek-1
### ai/
- ollama (GPU, RTX 2080 Ti, port 11434)
- openwebui (Postgres backend, port 8282)
### meshtastic/
- meshmonitor, meshmonitor-mqtt-proxy, meshmonitor-tileserver, meshtastic-map
## Planned / Not Yet Deployed
- dispatcharr, gotify, bytestash, kima-hub, n8n, qdrant, paperless-ngx, home-assistant
## Shelved
- scriberr — SQLite incompatible with ZFS nfsv4 ACLs
## Design Principles
- deterministic storage paths
- no anonymous volumes
- stack-local .env for secrets; .env.example committed with placeholders
- SSD for write-heavy / DB / SQLite / GPU workloads
- tank NFS for general appdata and configs
- Unraid NFS for media only
- databases stack uses `name: ix-databases` to maintain network name compatibility

View File

@@ -0,0 +1,77 @@
# Hardware Inventory
## Serenity (NAS / Media Ingestion)
- **OS:** Unraid 7.2.4
- **IP:** 10.5.1.5 | Tailscale: 100.94.87.79
- **CPU:** Xeon X5690
- **RAM:** 102GB
- **GPU:** None (Matrox IPMI only)
- **UPS:** None
### Storage
| Pool | Type | Drives | Usable | Notes |
|------|------|--------|--------|-------|
| malcolm | RAIDZ1 | 6× 10TB HDD | ~40TB | Heavily utilized |
| cache | ZFS single | 1× Kingston SNV2S 1TB NVMe | ~1TB | Appdata/Docker |
### Key Shares
| Share | Size | Purpose |
|-------|------|---------|
| data | 35TB | Media library |
| immich | 62GB | Immich photo storage |
| nextcloud | 7.4GB | Nextcloud data |
| Tesla/dashcam | 1.6TB | Dashcam footage |
| fizzlebang | 17GB | Personal files |
| isos | 22GB | ISO images |
| Syncthing | 4.6GB | Syncthing data |
| manndra | — | Partner's storage |
| Long and Low Crafts | — | Crafts business |
| zfs_backups_array | — | ZFS backup target |
---
## PlausibleDeniability (Primary Docker Host)
- **OS:** TrueNAS Scale 25.10.2.1
- **CPU:** Ryzen 9 3950X
- **RAM:** 32GB
- **GPU:** Nvidia RTX 2080 Ti (11GB VRAM) — Plex, Immich ML, Ollama
- **UPS:** None
### Storage
| Pool | Type | Mount | Notes |
|------|------|-------|-------|
| tank | ZFS mirror (2 drives) | `/mnt/tank` | ~3.5TB usable |
| docker-ssd | Single Crucial MX500 500GB | `/mnt/docker-ssd` | No redundancy |
| boot-pool | Single sdc3 | — | TrueNAS boot |
### NFS Mounts
- Serenity data array → `/mnt/unraid/data`
---
## N.O.M.A.D. (Offline Knowledge + Game Servers)
- **OS:** Ubuntu 25.10 (bare metal)
- **IP:** 10.5.1.16
- **CPU:** Intel Core i7-4770K @ 3.50GHz (4c/8t, up to 3.9GHz)
- **RAM:** 32GB DDR3 1600MHz (4×8GB)
- **GPU:** NVIDIA GeForce GTX 1080 (8GB VRAM)
- **NIC:** Intel I218-V (1GbE) + Aquantia AQC113 (10GbE)
- **Motherboard:** ASRock H97M Pro4
- **UPS:** None
### Storage
| Device | Size | Mount | Purpose |
|--------|------|-------|---------|
| Samsung SSD 840 (sdb) | 232.9GB | `/` (LVM 100GB) | OS boot |
| WD Red HDD (sda) | 3.6TB | `/mnt/hdd-1` | Primary data, project-nomad symlink |
| WD Red HDD (sdc) | 3.6TB | `/mnt/hdd-2` | Docker data-root |
| Seagate SSD (sdd) | 223.6GB | `/mnt/ssd-1` | Fast scratch |
---
## Desktop: ROCINANTE
- **OS:** Windows 11 Pro
- **CPU:** Ryzen 7 9850X3D
- **RAM:** 64GB
- **GPU:** RTX 4090 (24GB VRAM)
- **Role:** Heavy AI inference, local Ollama (expose via `OLLAMA_HOST=0.0.0.0`)

View File

@@ -0,0 +1,56 @@
# Homelab Networking Model
## Physical Network
- **Gear:** Unifi throughout
- **Main LAN:** 10.5.1.x (Trusted VLAN)
- **Other VLANs:** Cameras, Guest, IoT
- **Serenity IP:** 10.5.1.5
- **N.O.M.A.D. IP:** 10.5.1.16
- **PlausibleDeniability:** DHCP on LAN
## Remote Access
- **Pangolin VPS + Newt:** Services exposed as subdomains via reverse proxy. Newt agents run on PD and N.O.M.A.D.
- **Tailscale:** Personal remote access, runs on Serenity (100.94.87.79)
- **Cloudflared:** No longer used. Dead container on Serenity to be removed.
## DNS
- **Provider:** Cloudflare
- All public subdomains point at Pangolin VPS IP
## Known Public Subdomains
- `paccoco.com` → Pangolin VPS
- `panel.paccoco.com` → Pelican Panel (N.O.M.A.D.)
- `node1.paccoco.com` → Wings daemon (N.O.M.A.D., no auth)
- `meshmonitor.paccoco.com` → Meshmonitor (PD)
- `gitea.paccoco.com` → Gitea (PD)
- `ai.paccoco.com` → OpenWebUI (PD) — DNS/Pangolin resource pending
## Docker Networking (PlausibleDeniability)
### ix-databases_shared-databases
Created by the `databases` stack. The databases compose file uses `name: ix-databases` so Docker names the network `ix-databases_shared-databases`, matching what all other stacks declare as external.
Any stack connecting to shared-postgres, shared-mariadb, or shared-redis must declare:
```yaml
networks:
ix-databases_shared-databases:
external: true
```
### pangolin
Created at runtime by the `newt` container in the infrastructure stack. Any service needing reverse-proxy exposure must declare:
```yaml
networks:
pangolin:
external: true
```
### Internal Service Model
Internal services run HTTP only behind the reverse proxy. Compose service names used for internal DNS between services in the same stack/network.
## N.O.M.A.D. Networking Notes
- `panel.paccoco.com` added to `/etc/hosts``127.0.0.1` for NAT loopback
- nginx listens on 80 and 443 (self-signed cert) for Wings → Panel communication
- Wings uses `--ignore-certificate-errors` for local loopback
- Pangolin resource `node1.paccoco.com` has auth disabled (Wings handles its own auth)
- Minecraft port 25565 TCP/UDP goes directly via home router port forward, not through Pangolin

View File

@@ -0,0 +1,103 @@
# Services Directory
All running services across the homelab with ports, URLs, and backend info.
## PlausibleDeniability
### Databases (internal only)
| Service | Port | Backend | Notes |
|---------|------|---------|-------|
| shared-postgres | 5432 | — | immich-optimized, vectorchord + pgvector |
| shared-mariadb | 3306 | — | |
| shared-redis | 6379 | — | |
### Infrastructure
| Service | Internal Port | Public URL | Notes |
|---------|--------------|------------|-------|
| newt | — | — | Pangolin reverse proxy agent |
| homepage | — | — | Dashboard |
| dockhand | — | — | Container management |
| uptime-kuma | — | — | MariaDB backend |
| netdata | — | — | Metrics |
| tailscale | — | — | VPN |
### Media
| Service | Internal Port | Public URL | Notes |
|---------|--------------|------------|-------|
| plex | — | — | GPU passthrough, RTX 2080 Ti |
| tautulli | — | — | Plex analytics |
| audiobookshelf | — | — | Audiobooks |
| seerr | — | — | Postgres backend |
| calibre-web-automated | — | — | Ebooks |
### Photos
| Service | Internal Port | Public URL | Notes |
|---------|--------------|------------|-------|
| immich-server | — | — | Postgres + Redis, GPU |
| immich-ml | — | — | GPU, CUDA |
### Home
| Service | Internal Port | Public URL | Notes |
|---------|--------------|------------|-------|
| kitchenowl | — | — | Grocery/tasks |
| donetick | — | — | Postgres backend, selfhosted.yaml required |
| shlink | — | — | URL shortener, Postgres |
| shlink-web-client | — | — | |
| qui | — | — | qBittorrent UI, manages Serenity remotely |
### Dev
| Service | Internal Port | Public URL | Notes |
|---------|--------------|------------|-------|
| gitea | — | gitea.paccoco.com | Postgres backend |
| rackpeek | — | — | |
### AI
| Service | Internal Port | Public URL | Notes |
|---------|--------------|------------|-------|
| ollama | 11434 | — | GPU, RTX 2080 Ti |
| openwebui | 8282→8080 | ai.paccoco.com (pending) | Postgres backend |
### Meshtastic
| Service | Internal Port | Public URL | Notes |
|---------|--------------|------------|-------|
| meshmonitor | 8081→3001 | meshmonitor.paccoco.com | Postgres backend |
| meshmonitor virtual node | 4404 | — | TCP virtual node server |
| meshmonitor-tileserver | 8082→8080 | — | Map tiles |
| meshmonitor-mqtt-proxy | — | — | MQTT→TCP bridge |
---
## Serenity
### Media Ingestion
| Service | Notes |
|---------|-------|
| sonarr | TV |
| sonarr-anime | Anime |
| radarr | Movies |
| lidarr | Music |
| readarr | Books |
| readarr-epub | EPUBs |
| prowlarr | Indexer manager |
| bazarr | Subtitles |
| unpackerr | Archive extraction |
| qBittorrent | Download client |
| GluetunVPN | VPN tunnel for qbit |
| autobrr | Auto-grab |
| qbit_manage | qBit maintenance |
| Notifiarr | Notifications |
| Wizarr | User invites |
| romm | ROM manager |
| GameVault | Game library |
| shelfmark | Book/audiobook search, port 8084 |
---
## N.O.M.A.D.
| Service | Port | Notes |
|---------|------|-------|
| Pelican Panel | 80/443 | panel.paccoco.com, PHP 8.4 + nginx + MariaDB |
| Wings | 8443 | node1.paccoco.com, game server daemon |
| Minecraft | 25565 | Purpur, Java 21, direct port forward |
| N.O.M.A.D. containers | — | 10 containers, start_nomad.sh / stop_nomad.sh |