# Homelab Overview **Last Updated:** June 13, 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 | ### Wi-Fi Infrastructure Wireless coverage is provided by a **Synology mesh network** running SRM (Synology Router Manager). | Device | Model | IP | Location | Role | |---|---|---|---|---| | Primary Router | Synology RT6600ax | 192.168.88.57 | Basement utility room | Main mesh router — tri-band Wi-Fi 6 | | Mesh Point 1 | Synology MR2200ac | — | Living room | Mesh satellite — Wi-Fi 5 | | Mesh Point 2 | Synology MR2200ac | — | Shop (separate building) | Mesh satellite — Wi-Fi 5 | **SSIDs:** | SSID | Band | Purpose | |---|---|---| | JG | 5 GHz | Primary wireless network | | iot24 | 2.4 GHz | Home automation / IoT devices | The RT6600ax in the basement is the mesh base station. The living room MR2200ac covers the main floor, and the shop unit extends coverage to the separate outbuilding. All three are managed from the same SRM interface. ### 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 runs all the VMs and LXC containers listed below. Backups are handled by the PBS VM (VM 107). NFS storage is provided by TrueNAS (separate physical machine, see below). ### Virtual Machines | VM ID | Name | IP | RAM | Status | Role | |---|---|---|---|---|---| | 102 | jellyfin | 192.168.88.10 | 14 GB | Running | Media server (Jellyfin + arr stack) | | 103 | next | 192.168.88.62 | 8 GB | Running | Nextcloud | | 105 | openclaw-debian | — | 4 GB | Stopped | spare/dev VM | | 106 | haos-16.3 | — | 10 GB | Running | Home Assistant OS | | 107 | pbs | 192.168.88.60 | 8 GB | Running | Proxmox Backup Server | | 112 | docker-server (siklos) | 192.168.88.27 | 16 GB | Running | Main Docker host | | 113 | photos | 192.168.88.32 | 16 GB | Running | Photo services (Immich) | | 120 | opnsense | — | 4 GB | Stopped | OPNsense firewall/router (not active) | | 9000 | debian13-template | — | 4 GB | Stopped | Base template for new VMs | ### LXC Containers | CT ID | Name | IP | RAM | Status | Role | |---|---|---|---|---|---| | 200 | gitea | — | 512 MB | Running | Gitea LXC instance | | 202 | caddy | 192.168.88.110 | 512 MB | Running | Caddy reverse proxy (systemd inside LXC) | ### Physical Machines | Name | IP | Role | |---|---|---| | jgpc | 192.168.88.41 | Workstation / AI / Ollama (bare metal, not a Proxmox guest) | | TrueNAS | 192.168.88.24 | NAS — provides NFS storage for Kopia backups; separate physical machine | --- ## 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 jgpc, 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//` 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 jgpc) | | 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 | 9108–9109 | — | 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. --- ### jgpc — 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 | #### Printing (jgpc) The jgpc is the print server for the HP PageWide Color Flow MFP 586. | Item | Value | |---|---| | Printer | HP PageWide Color Flow MFP 586 | | IP | 192.168.88.89 (static DHCP reservation, MAC: `ec:8e:b5:c0:d0:48`) | | CUPS queue | `HP_586_MFP` (default) | | Device URI | `ipps://192.168.88.89/ipp/print` | | Driver | IPP Everywhere (driverless) | `cups-browsed` is **disabled** — it was auto-recreating an unstable mDNS-based queue whenever the printer was online. The printer is permanently saved in `/etc/cups/printers.conf` with a static IP URI. --- ### 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 | Photo storage is on a local 200 GB SSD (`/mnt/immich-photos`) — migrated from TrueNAS NFS in May 2026 for better performance. > **Note (2026-05-11):** PhotoPrism was removed. The Docker image was deleted to free ~3.6 GB of disk space. Photo data has been retained. --- ## Monitoring Prometheus scrapes **Node Exporter** (port 9100) from every host: siklos, proxmox, Nextcloud, jellyfin, PBS, caddy, and jgpc. **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 |