{"id":38000944,"url":"https://github.com/ionfury/homelab","last_synced_at":"2026-04-23T05:00:56.237Z","repository":{"id":65565856,"uuid":"476513139","full_name":"ionfury/homelab","owner":"ionfury","description":"Tom's Homelab mono repository","archived":false,"fork":false,"pushed_at":"2026-04-19T11:20:16.000Z","size":17783,"stargazers_count":22,"open_issues_count":17,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-19T13:20:09.208Z","etag":null,"topics":["devops","harvester","k8s-at-home","kubernetes","rancher","rke"],"latest_commit_sha":null,"homepage":"","language":"YAML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"wtfpl","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ionfury.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-03-31T23:47:01.000Z","updated_at":"2026-04-19T11:20:20.000Z","dependencies_parsed_at":"2023-12-20T06:44:42.034Z","dependency_job_id":"fa04c50a-3887-4e08-970d-73e57831b904","html_url":"https://github.com/ionfury/homelab","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/ionfury/homelab","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ionfury%2Fhomelab","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ionfury%2Fhomelab/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ionfury%2Fhomelab/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ionfury%2Fhomelab/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ionfury","download_url":"https://codeload.github.com/ionfury/homelab/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ionfury%2Fhomelab/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32166660,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-23T02:19:40.750Z","status":"ssl_error","status_checked_at":"2026-04-23T02:17:55.737Z","response_time":53,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["devops","harvester","k8s-at-home","kubernetes","rancher","rke"],"created_at":"2026-01-16T19:13:06.771Z","updated_at":"2026-04-23T05:00:56.229Z","avatar_url":"https://github.com/ionfury.png","language":"YAML","readme":"# 🏠 ionfury-homelab\n\nThis repo documents my homelab infrastructure and GitOps configuration. I've recently rebuilt the whole stack on Talos, moving away from Rancher and Harvester. This setup is fully declarative, modular, and automated from PXE to production workloads.\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\n![heartbeat](https://img.shields.io/badge/dynamic/json?color=brightgreen\u0026label=heartbeat\u0026query=%24.status\u0026url=https%3A%2F%2Fhealthchecks.io%2Fbadge%2Fb4308338-139b-4907-bee3-37c2da%2FiS3vfgkr-2.json\u0026style=flat-square\u0026logo=kubernetes\u0026logoColor=white)\u0026nbsp;\u0026nbsp;\n[![30D-Availability](https://img.shields.io/endpoint?url=https%3A%2F%2Fstats.tomnowak.work%2Fquery%3Fformat%3Dendpoint%26metric%3Dapiserver_availability_30d\u0026style=flat-square\u0026label=Availability)](https://github.com/kashalls/kromgo/)\u0026nbsp;\u0026nbsp;\n[![Node-Count](https://img.shields.io/endpoint?url=https%3A%2F%2Fstats.tomnowak.work%2Fquery%3Fformat%3Dendpoint%26metric%3Dcluster_node_count\u0026style=flat-square\u0026label=Nodes)](https://github.com/kashalls/kromgo/)\u0026nbsp;\u0026nbsp;\n[![Pod-Count](https://img.shields.io/endpoint?url=https%3A%2F%2Fstats.tomnowak.work%2Fquery%3Fformat%3Dendpoint%26metric%3Dcluster_pod_count\u0026style=flat-square\u0026label=Pods)](https://github.com/kashalls/kromgo/)\u0026nbsp;\u0026nbsp;\n[![CPU-Usage](https://img.shields.io/endpoint?url=https%3A%2F%2Fstats.tomnowak.work%2Fquery%3Fformat%3Dendpoint%26metric%3Dcluster_cpu_usage\u0026style=flat-square\u0026label=CPU)](https://github.com/kashalls/kromgo/)\u0026nbsp;\u0026nbsp;\n[![Memory-Usage](https://img.shields.io/endpoint?url=https%3A%2F%2Fstats.tomnowak.work%2Fquery%3Fformat%3Dendpoint%26metric%3Dcluster_memory_usage\u0026style=flat-square\u0026label=Memory)](https://github.com/kashalls/kromgo/)\u0026nbsp;\u0026nbsp;\n[![Power-Usage](https://img.shields.io/endpoint?url=https%3A%2F%2Fstats.tomnowak.work%2Fquery%3Fformat%3Dendpoint%26metric%3Dcluster_power_usage\u0026style=flat-square\u0026label=Power)](https://github.com/kashalls/kromgo/)\u0026nbsp;\u0026nbsp;\n\n\u003c/div\u003e\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\n![Talos](https://img.shields.io/badge/Talos-1.10.4-blue?logo=kubernetes\u0026style=for-the-badge)\n![Kubernetes](https://img.shields.io/badge/Kubernetes-1.33.0-blue?logo=kubernetes\u0026style=for-the-badge)\n![Terragrunt](https://img.shields.io/badge/Terragrunt-0.81.5-blue?logo=terraform\u0026style=for-the-badge)\n![OpenTofu](https://img.shields.io/badge/OpenTofu-1.8.9-blue?logo=terraform\u0026style=for-the-badge)\n\n\u003c/div\u003e\n\n---\n\n## Overview\n\nThis repository contains the infrastructure and GitOps configuration for my homelab. The current iteration is based on Talos Linux and Kubernetes, with everything deployed and reconciled through Flux. Provisioning is handled via PXE boot and Terragrunt modules for Talos-based clusters.\n\nThe entire stack is declarative, built to be reproducible, and optimized for hands-off operation. My goal here is to push the boundaries of what \"infrastructure as code\" actually means—starting from the BIOS and ending at an SLO dashboard.\n\n---\n\n## Table of Contents\n\n- [Overview](#overview)\n- [Directories](#directories)\n- [Architecture](#architecture)\n  - [Hardware](#hardware)\n  - [Cloud Dependencies](#cloud-dependencies)\n  - [Networking](#networking)\n- [Bare Metal](#bare-metal)\n- [Provisioning](#provisioning)\n- [Deployment](#deployment)\n- [License](#license)\n\n---\n\n## Directories\n\n```\n📁\n├─ .github/          # GitHub workflows and actions\n├─ .taskfiles/       # Reusable task automation with taskfile.dev\n├─ docs/             # Runbooks and notes\n├─ infrastructure/   # PXE + cluster provisioning via Terragrunt\n├─ kubernetes/       # Flux-based GitOps manifests per cluster\n├─ Taskfile.yaml     # Root taskfile entry\n```\n\n---\n\n## Architecture\n\nThis setup has grown to support multiple environments and workload isolation via dedicated physical clusters. It's designed to withstand full cluster outages without taking down the rest of the network.\n\nThe network is segmented using VLANs, with one segment (`citadel`) allocated for Kubernetes infrastructure. PXE, DNS, and initial bootstrapping all happen within this VLAN.\n\n\u003cdetails\u003e\n  \u003csummary\u003eClick to see vlan diagram\u003c/summary\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/ionfury/homelab/main/docs/images/home-network-firewall.png\" align=\"center\" alt=\"firewall\"/\u003e\n\u003c/details\u003e\n\n---\n\n### Hardware\n\n| Device | CPU | RAM | Disks | Purpose |\n|--------|-----|-----|-------|---------|\n| Supermicro Nodes | Xeon E5 / D / 8C | 32-128GB | SSDs + HDDs | Talos cluster nodes |\n| Pi 4 | ARM | 2-8GB | microSD | PXE, PXE DHCP, or test clusters |\n| Unifi Aggregation | - | - | - | 10G switch |\n| CyberPower UPS | - | - | - | Battery backup and monitoring |\n\n\u003cdetails\u003e\n  \u003csummary\u003eFront of rack\u003c/summary\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/ionfury/homelab/main/docs/images/rack-front.jpg\" align=\"center\" alt=\"rack-front\"/\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003eBack of rack\u003c/summary\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/ionfury/homelab/main/docs/images/rack-back.jpg\" align=\"center\" alt=\"rack-back\"/\u003e\n\u003c/details\u003e\n\n---\n\n### Cloud Dependencies\n\n| Tool       | Purpose                     | Cost        |\n|------------|-----------------------------|-------------|\n| GitHub     | GitOps, CI/CD, tokens       | Free        |\n| Cloudflare | DNS + public exposure       | ~$10/year   |\n| AWS S3     | Terraform state, secrets    | ~$10/year   |\n| Healthchecks.io | Heartbeats, Uptime    | Free        |\n\nTotal: ~$20/year\n\n---\n\n\n## Networking\n\nNetworking is handled via Unifi. The Talos cluster nodes reside in the `192.168.10.0/24` subnet, statically assigned by MAC. Talos is configured to use this subnet for the control plane VIP, service IPs, and ingress routing.\n\nAll cluster networks are Cilium-native and pods are assigned from separate /16 subnets per environment.\n\nIngress is exposed via NGINX with dedicated internal and external IPs. Blocky provides local DNS resolution and filtering.\n\n---\n\n## Bare Metal\n\nNodes are installed via PXE boot into Talos Linux. The PXE boot environment is managed declaratively through Terragrunt and includes MAC address mapping and static IP assignments.\n\nSupermicro hardware is configured through IPMI with automation for NTP, naming, and password rotation documented in `docs/runbooks`.\n\n---\n\n## Provisioning\n\nTalos clusters are provisioned via `terragrunt apply` from the `infrastructure/clusters` directory. Each cluster environment has its own set of HCL configurations that map hosts, IPs, and versions.\n\nClusters boot directly into Talos, join the cluster, and install Flux which begins reconciling workloads from the `kubernetes/` folder.\n\nExample provisioning command:\n\n```sh\ncd infrastructure/clusters/live\nterragrunt apply\n```\n\n---\n\n## Deployment\n\nFlux watches the cluster folder and automatically applies all manifests from the corresponding `kubernetes/clusters/\u003cenv\u003e` directory.\n\nComponents are organized by namespace and include:\n\n- Cert Manager\n- Longhorn\n- Monitoring Stack (Prometheus, Grafana, Loki, etc.)\n- Ingress (NGINX)\n- Cilium\n- External Secrets\n- Custom workloads\n\nChanges are committed to Git and picked up automatically via GitOps.\n\n---\n\n## Network Policy\n\nNetwork security is enforced using `NetworkPolicy` objects. Policies are structured as reusable components inside `.network-policies/`.\n\nEach policy defines a `source/` and `destination/` and is bound to namespaces via Kustomize components and pod labels like `networking/allow-egress-to-postgres`.\n\nA namespace can \"opt-in\" to default deny behavior by applying `allow-same-namespace`.\n\n---\n\n## Acknowledgements\n\nThanks to the Kubernetes@Home Discord community for all the shared patterns and tools. If you're building something similar, start there.\n\n---\n\n## License\n\nSee [LICENSE](./LICENSE)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fionfury%2Fhomelab","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fionfury%2Fhomelab","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fionfury%2Fhomelab/lists"}