Files
homelab-configs/homelab-overview.md
T

196 lines
9.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Homelab Overview
**Last Updated:** May 2026
This document provides a high-level summary of the entire homelab infrastructure — networking, physical/virtual hosts, Docker services, and how everything is connected.
---
## Network Overview
The homelab runs on a **192.168.88.0/24** subnet managed by a **MikroTik router** at `192.168.88.1`.
| Role | Device | IP |
|---|---|---|
| Primary Router / DNS | MikroTik | 192.168.88.1 |
| Secondary Network | Secondary subnet | 192.168.2.0/24 |
### DNS Architecture
- **MikroTik** handles all internal DNS. It resolves `*.jgitta.com` subdomains to the internal Caddy reverse proxy at `192.168.88.110`, and forwards everything else to `1.1.1.1` / `8.8.8.8`.
- **Pi-hole** (on siklos, `192.168.88.27`) sits between clients and MikroTik as a DNS ad blocker. Its only upstream is the MikroTik (`192.168.88.1`) — not public DNS directly — so that local domain resolution stays consistent.
- **Cloudflare DNS** manages external DNS for `jgitta.com` and `goldengamer.org`. Public-facing services point to the WAN IP (grey cloud), which port-forwards 443 → Caddy VM.
### External Access
All inbound HTTPS traffic hits the **MikroTik** WAN interface, which port-forwards port 443 to the **Caddy VM** at `192.168.88.110`. Caddy terminates TLS (via Let's Encrypt + Cloudflare DNS challenge) and reverse-proxies to the appropriate internal service.
---
## Physical & Virtual Infrastructure
### Proxmox Hypervisor
| Item | Value |
|---|---|
| Host | `192.168.88.25` |
| Proxmox Backup Server (PBS) | `192.168.88.60` |
| TrueNAS (NAS / NFS storage) | `192.168.88.24` |
Proxmox runs all the VMs listed below. PBS provides nightly VM backups. TrueNAS provides NFS storage used by Kopia backups and (previously) photo storage.
### Virtual Machines
| VM ID | Alias | IP | Role |
|---|---|---|---|
| VM 103 | next | 192.168.88.62 | Nextcloud |
| VM 112 | siklos / docker-server | 192.168.88.27 | Main Docker host (4 vCPU / 12 GB RAM) |
| VM 113 | photos | 192.168.88.32 | Photo services (Immich + PhotoPrism) |
| — | jellyfin | 192.168.88.10 | Media server host |
| — | caddy | 192.168.88.110 | Reverse proxy (systemd service, not Docker) |
| — | thinkstation-p710 | 192.168.88.41 | Workstation / AI / Ollama |
---
## Reverse Proxy — Caddy (192.168.88.110)
Caddy runs as a **systemd service** (not Docker) on a dedicated VM. It handles all `*.jgitta.com` HTTPS termination.
Config location on the Caddy VM: `/etc/caddy/`
| File | Purpose |
|---|---|
| `Caddyfile` | Main entry point — global options, imports all site files |
| `snippets.caddy` | Reusable blocks: `web_secure`, `internal_only`, `proxy_timeouts` |
| `sites/infrastructure.caddy` | Management tools (Portainer, Grafana, Pi-hole, Kopia, etc.) |
| `sites/media.caddy` | Media stack (Jellyfin, Sonarr, Radarr, Nextcloud, etc.) |
| `sites/homenet.caddy` | Internal `.homenet` HTTP-only domains |
| `sites/goldengamer.caddy` | External `goldengamer.org` domain |
**Key security note:** The `internal_only` snippet blocks all requests from outside `192.168.88.0/24` and `192.168.2.0/24`. Sensitive services (Portainer, Pi-hole, Proxmox, etc.) use this snippet.
---
## Docker Infrastructure
Docker is managed centrally via **Portainer CE** at `http://192.168.88.27:9000` (external: `https://portainer.jgitta.com`). Portainer agents run on jellyfin and thinkstation, allowing all three hosts to be managed from one UI.
All Docker Compose source files live in the **Gitea** repo `jgitta/homelab-configs` (this repo).
All stack data volumes are stored at `/srv/docker/<stack-name>/` on each host using **absolute paths**.
---
### siklos — 192.168.88.27 (VM 112) — Main Docker Host
| Service | Image | Port | URL | Purpose |
|---|---|---|---|---|
| Portainer | portainer/portainer-ce:latest | 9000, 9443 | portainer.jgitta.com | Docker management UI |
| Pi-hole | pihole/pihole:latest | 53 (DNS), 8080 | pihole.jgitta.com | DNS ad blocker |
| Open WebUI | ghcr.io/open-webui/open-webui:main | 3000 | ai.jgitta.com | AI chat UI (connects to Ollama on ThinkStation) |
| LiteLLM | litellm:latest | 4000 | — | Centralized LLM API gateway |
| OnlyOffice | onlyoffice/documentserver | 8880 | office.jgitta.com | Online document editing (used by Nextcloud) |
| Homarr | homarr:latest | 7575 | homarr.jgitta.com | Dashboard |
| Dashy | lissy93/dashy:latest | 8081 | dashy.jgitta.com | Dashboard |
| Uptime Kuma | uptime-kuma:2 | 3001 | status.jgitta.com | Uptime monitoring |
| Grafana | grafana:latest | 3020 | grafana.jgitta.com | Metrics dashboards |
| Prometheus | prom/prometheus:latest | 9090 | — | Metrics collection |
| Node Exporter | prom/node-exporter:latest | 9100 | — | Host metrics (runs on all nodes) |
| cAdvisor | cadvisor:latest | 8090 | — | Container metrics |
| Graphite Exporter | prom/graphite-exporter:latest | 91089109 | — | Graphite metrics bridge |
| Glances | nicolargo/glances:latest | 61208 | glances.jgitta.com | System resource monitor |
| MeshCentral | typhonragewind/meshcentral:latest | 444 | mesh.jgitta.com | Remote device management |
| Guacamole | jwetzell/guacamole | 8080 | apache.jgitta.com | Remote desktop gateway |
| Karakeep | karakeep:release | 3010 | notes.jgitta.com | Bookmarks / read-later |
| Linkwarden | linkwarden:latest | 3015 | links.jgitta.com | Link manager |
| Gitea | gitea:latest | 3002, 2222 | gitea.jgitta.com | Self-hosted Git server |
| Kopia | kopia:latest | 51515 | kopia.jgitta.com | Backup tool → TrueNAS NFS |
| Actual Budget | actual-budget | 5006 | budget.jgitta.com | Personal budget tracking |
| WordPress | wordpress:php8.3-apache | 8095 | jgitta.com | Personal website |
| WordPress DB | mariadb:10.11 | 3306 (internal) | — | WordPress database |
| Grav | linuxserver/grav:latest | 8585 | — | Flat-file CMS |
| Watchtower | containrrr/watchtower | — | — | Auto-updates containers (excludes Pi-hole) |
| GoldenGames | goldengames (local build) | 3030 | goldengamer.org | Gaming site |
---
### jellyfin — 192.168.88.10 — Media Server Host
| Service | Image | Port | Purpose |
|---|---|---|---|
| Jellyfin | jellyfin/jellyfin:latest | 8096 | Media streaming server |
| Radarr | lscr.io/linuxserver/radarr:latest | 7878 | Movie automation |
| Sonarr | lscr.io/linuxserver/sonarr:latest | 8989 | TV show automation |
| Prowlarr | lscr.io/linuxserver/prowlarr:latest | 9696 | Indexer manager for Radarr/Sonarr |
| FlareSolverr | ghcr.io/flaresolverr/flaresolverr:latest | 8191 | Cloudflare bypass for indexers |
| Watchtower | containrrr/watchtower | — | Auto-updates arr-stack containers |
| Node Exporter | prom/node-exporter:latest | 9100 (host) | Prometheus metrics |
| Portainer Agent | portainer/agent:latest | 9001 | Managed by siklos Portainer |
Media storage is mounted at `/mnt/media` on the jellyfin host and presented as `/data` inside Radarr and Sonarr.
---
### thinkstation-p710 — 192.168.88.41 — AI / Workstation Host
| Service | Image | Port | Purpose |
|---|---|---|---|
| Ollama | ollama/ollama:latest | 11434 (internal) | Local LLM inference engine |
| Open WebUI | ghcr.io/open-webui/open-webui:main | 3000 | AI chat UI (local, also proxied via siklos) |
| Frigate | blakeblackshear/frigate:stable | 5000, 8554, 8555 | NVR / AI camera motion detection |
| Stirling PDF | frooodle/s-pdf:latest | 8081 | PDF tools web UI |
| Portainer Agent | portainer/agent:latest | 9001 | Managed by siklos Portainer |
---
### photos VM — 192.168.88.32 (VM 113) — Photo Services
| Service | Image | Port | Purpose |
|---|---|---|---|
| Immich | ghcr.io/immich-app/immich-server:release | 2283 | Google Photos replacement |
| PhotoPrism | photoprism/photoprism:latest | 2342 | Photo management & AI tagging |
Photo storage is on a local 200 GB SSD (`/mnt/immich-photos`) — migrated from TrueNAS NFS in May 2026 for better performance.
---
## Monitoring
Prometheus scrapes **Node Exporter** (port 9100) from every host: siklos, proxmox, Nextcloud, jellyfin, PBS, caddy, and ThinkStation. **Grafana** at `grafana.jgitta.com` visualizes all metrics and fires alerts (via Telegram) when:
- RAM > 90% for 5 minutes
- Swap > 50% for 5 minutes
- CPU > 90% for 10 minutes
- Disk > 85% for 5 minutes
- Any node goes down for 2 minutes
**Uptime Kuma** at `status.jgitta.com` provides service-level uptime monitoring with a public status page.
---
## Backup Strategy
| Source | Tool | Destination |
|---|---|---|
| All VMs | Proxmox Backup Server (PBS) | Local PBS at 192.168.88.60 |
| Nextcloud data | Kopia (Docker on siklos) | TrueNAS NFS |
| Immich photos | Kopia (Docker on VM 113) | Backblaze B2 |
| Docker configs | Gitea repo | `jgitta/homelab-configs` |
---
## Key URLs
| Service | URL |
|---|---|
| Portainer | https://portainer.jgitta.com |
| Grafana | https://grafana.jgitta.com |
| Pi-hole | https://pihole.jgitta.com |
| Uptime Kuma | https://status.jgitta.com |
| Gitea | https://gitea.jgitta.com |
| Jellyfin | https://jellyfin.jgitta.com |
| Nextcloud | https://next.jgitta.com |
| Immich | https://photos.jgitta.com |
| AI (Open WebUI) | https://ai.jgitta.com |
| Guacamole | https://apache.jgitta.com |
| Kopia | https://kopia.jgitta.com |