# homelab Infrastructure-as-Code for a 3-machine homelab running K3s. ## Status | Phase | Description | Status | |---|---|---| | 0 | Backup configs, init repo | ✅ Done | | 1 | Bootstrap Minisforum — K3s server + Traefik | ✅ Done | | 2 | Join Debian as K3s agent, SMB setup | ⏳ Next | | 3 | Deploy core infra — Gitea, Pi-hole, DDNS | 🔧 In progress | | 4 | Deploy app services — Jellyfin, qBittorrent, JDownloader, Dashy, Glances | 🔜 Planned | | 5 | Networking cutover — router, Traefik ingress, DNS | 🔜 Planned | | 6 | Cleanup legacy Debian services | 🔜 Planned | ## Architecture | Machine | IP | SSH Port | Role | Status | |---|---|---|---|---| | Minisforum UM780 XTX | 192.168.7.77 | 430 | K3s server, main gateway | ✅ Running — K3s + Traefik | | Debian Server (HP ProDesk) | TBD | — | K3s agent, SMB storage | ⏳ Phase 2 | | Mac Mini M2 | TBD | — | Standalone (outside cluster) | ⏳ Phase 3+ | ## Internal Services (Minisforum) | Service | URL | Notes | |---|---|---| | Traefik | — | Ingress controller, Let's Encrypt | | Authentik | `https://authentik.home.arpa` | SSO/identity provider | | Gitea | `https://gitea.home.arpa` | Git + Docker registry, SSH on port 2222 | | Pi-hole | `https://pihole.home.arpa/admin` | Primary DNS, resolves `*.home.arpa` → 192.168.7.77 | | Grafana | `https://grafana.home.arpa` | Monitoring dashboards (kube-prometheus-stack) | | Jellyfin | `https://jellyfin.home.arpa` | Media server | | qBittorrent | `https://qbittorrent.home.arpa` | Torrent client | | JDownloader | `https://jdownloader.home.arpa` | Download manager | | Dashy | `https://dashy.home.arpa` | Dashboard | | Glances | `https://glances.home.arpa` | System monitoring | ## Repo Structure ``` ansible/ inventory.yaml # host definitions playbooks/ bootstrap-minisforum.yaml # OS hardening, packages, UFW, /data dirs deploy-watch-party.yaml # deploy watch-party app join-debian-agent.yaml # join Debian as K3s agent setup-gitea-runner.yaml # set up Gitea Actions runner setup-glances-debian.yaml # deploy Glances on Debian host setup-k3s.yaml # K3s server install, Helm, kubeconfig setup-monitoring.yaml # deploy monitoring stack setup-nfs-debian.yaml # configure NFS server on Debian roles/ common/ # user, SSH hardening, UFW, base packages gitea-runner/ # Gitea Actions runner setup glances/ # Glances system monitor k3s-agent/ # K3s agent node join k3s-server/ # K3s server install + Helm monitoring/ # Prometheus/Grafana monitoring nfs-server/ # NFS server configuration watch-party/ # Watch-party app deployment config/ dashy/conf.yaml # Dashy dashboard config manifests/ authentik/ # Authentik ingress, middleware, proxy outpost, secrets cert-manager/ # ClusterIssuers and porkbun-secret.sh core/ # Dashy, Glances, CA installer, apply-dashy-config.sh gitea/ # Gitea PV, runner, backup, runner secret media/ # Jellyfin, qBittorrent, JDownloader monitoring/ # Grafana/Loki datasource, PVs, grafana-secret.sh network/ # DDNS, Traefik dashboard, ingress routes, pihole patch values/ authentik.yaml # Authentik SSO cert-manager.yaml # cert-manager gitea.yaml # Gitea kube-prometheus-stack.yaml # Prometheus + Grafana loki-stack.yaml # Loki log aggregation pihole.yaml # Pi-hole (Minisforum) pihole-debian.yaml # Pi-hole (Debian) traefik.yaml # Traefik ingress controller ``` ## Prerequisites - Ansible installed on your workstation: `pip install ansible` - Ansible collections: `ansible-galaxy collection install community.general ansible.posix` - SSH key at `~/.ssh/id_ed25519-nik-macbookair` ## Connecting ```bash # SSH ssh minisforum # port 430, configured via ~/.ssh/config # Kubectl (after fetching kubeconfig) export KUBECONFIG=/tmp/k3s-minisforum.yaml kubectl get nodes kubectl get pods -A ``` ## Deploying / Re-deploying ```bash # Re-run bootstrap (idempotent) ansible-playbook -i ansible/inventory.yaml ansible/playbooks/bootstrap-minisforum.yaml # Re-run K3s setup (idempotent) ansible-playbook -i ansible/inventory.yaml ansible/playbooks/setup-k3s.yaml # Traefik helm repo add traefik https://helm.traefik.io/traefik && helm repo update helm upgrade --install traefik traefik/traefik \ --namespace traefik --create-namespace \ -f values/traefik.yaml # Gitea helm repo add gitea-charts https://dl.gitea.com/charts/ && helm repo update helm upgrade --install gitea gitea-charts/gitea \ --namespace gitea --create-namespace \ -f values/gitea.yaml # Pi-hole helm repo add mojo2600 https://mojo2600.github.io/pihole-kubernetes/ && helm repo update helm upgrade --install pihole mojo2600/pihole \ --namespace pihole --create-namespace \ -f values/pihole.yaml # cert-manager helm repo add jetstack https://charts.jetstack.io && helm repo update helm upgrade --install cert-manager jetstack/cert-manager \ --namespace cert-manager --create-namespace \ -f values/cert-manager.yaml # Authentik helm repo add authentik https://charts.goauthentik.io && helm repo update helm upgrade --install authentik authentik/authentik \ --namespace authentik --create-namespace \ -f values/authentik.yaml # kube-prometheus-stack helm repo add prometheus-community https://prometheus-community.github.io/helm-charts && helm repo update helm upgrade --install kube-prometheus-stack prometheus-community/kube-prometheus-stack \ --namespace monitoring --create-namespace \ -f values/kube-prometheus-stack.yaml # Loki helm repo add grafana https://grafana.github.io/helm-charts && helm repo update helm upgrade --install loki grafana/loki-stack \ --namespace monitoring --create-namespace \ -f values/loki-stack.yaml ```