https://github.com/mortylabs/kubernetes
Andrew Morty's production-grade K3s homelab on Raspberry Pi â Home Assistant, InfluxDB, Grafana, MQTT, Pi-hole, deCONZ, UniFi, Cloudflare DDNS and more
https://github.com/mortylabs/kubernetes
cert-manager cloudflare-ddns docker esp8266 grafana home-assistant homelab influxdb ingress-nginx iot k3s k8s kubernetes metallb mongodb morty mqtt python3 raspberry-pi wordpress
Last synced: 2 months ago
JSON representation
Andrew Morty's production-grade K3s homelab on Raspberry Pi â Home Assistant, InfluxDB, Grafana, MQTT, Pi-hole, deCONZ, UniFi, Cloudflare DDNS and more
- Host: GitHub
- URL: https://github.com/mortylabs/kubernetes
- Owner: mortylabs
- License: gpl-3.0
- Created: 2021-06-26T07:18:46.000Z (almost 5 years ago)
- Default Branch: main
- Last Pushed: 2026-03-15T21:28:36.000Z (3 months ago)
- Last Synced: 2026-04-11T09:49:15.263Z (2 months ago)
- Topics: cert-manager, cloudflare-ddns, docker, esp8266, grafana, home-assistant, homelab, influxdb, ingress-nginx, iot, k3s, k8s, kubernetes, metallb, mongodb, morty, mqtt, python3, raspberry-pi, wordpress
- Language: Shell
- Homepage: https://mortylabs.com
- Size: 327 KB
- Stars: 26
- Watchers: 3
- Forks: 4
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# đ Morty Labs â K3s Homelab
> A lightweight K3s-based Kubernetes cluster, currently running version **`v1.34.4+k3s1`** as of **25th February 2026**, tailored for a personal homelab hosting `Home Assistant`, `InfluxDB`, `Grafana`, `MQTT`, `UniFi Controller`, `Pi-hole`, `deCONZ`, and more.
[](https://k3s.io/)
[](https://cert-manager.io/)
[](https://metallb.universe.tf/)
[](https://kubernetes.github.io/ingress-nginx/)
[](LICENSE)
[](https://github.com/mortylabs/kubernetes/stargazers)
[](https://github.com/mortylabs/kubernetes/actions/workflows/lint.yaml)



---
## đ¤ Why This Repo Exists
To better understand Kubernetes concepts, I wrote all deployment `.yaml` files myself from scratch, instead of relying on third-party Helm charts:
- Fully orchestrated Kubernetes stack built for **Raspberry Pi**
- Ideal for self-hosted services: Home Assistant, databases, dashboards, network management, and more
- Modular and portable â spin up the same stack at home or at a remote site
- Secure by default â TLS everywhere, Cloudflare WAF in front, fail2ban on the nodes
---
## đ¤ Who Is This For?
- Raspberry Pi enthusiasts wanting to run a production-grade homelab or website
- Home Assistant users who want persistent storage, TLS, and proper ingress
- Anyone learning Kubernetes who wants real working manifests, not toy examples
- DevOps engineers setting up a low-cost remote monitoring stack
---
## đŻ What You'll End Up With
A fully working homelab cluster with:
- đĄ Home Assistant accessible at `https://ha.yourdomain.com`
- đ Grafana dashboards at `https://grafana.yourdomain.com`
- đ Automatic TLS certificates via Let's Encrypt
- đĄ MQTT broker for all your IoT sensors
- đłď¸ Network-wide ad blocking via Pi-hole
- âď¸ Automatic DNS updates when your home IP changes
- đž All data persisted on NFS â survives pod restarts and reboots
---
## đ Cluster Overview
- **Kubernetes Distribution:** [Rancher K3s](https://k3s.io/)
- **Load Balancer:** [MetalLB](https://metallb.universe.tf/) v0.15.3
- **Ingress/Reverse Proxy:** [ingress-nginx](https://kubernetes.github.io/ingress-nginx/) v1.12.0 (replacing the default Traefik)
- **TLS:** [cert-manager](https://cert-manager.io/) v1.19.4 + Let's Encrypt
- **DNS/CDN:** [Cloudflare](https://cloudflare.com) (proxy + WAF + DDNS)
- **Nodes:** Raspberry Pi 4 Model B â ARM64, 8GB RAM
- **Operating System:** Raspberry Pi OS (Bookworm) 64-bit
- **Storage:** Dedicated Raspberry Pi NFS server (SSD-based, 500GB)
- **Backups:** Automatic backups to Google Drive and GitHub
Feel free to explore, reuse, or adapt this repo for your own Kubernetes learning journey!
---
## đŚ Deployed Services
- [`home-assistant`](home-assistant/) â Core home automation hub
- [`influxdb`](influxdb/) â Time-series metrics storage
- [`grafana`](grafana/) â Metrics dashboards
- [`mqtt_broker`](mqtt_broker/) â Mosquitto MQTT broker
- [`mqtt2influx`](mqtt2influx/) â MQTT â InfluxDB bridge
- [`govee2mqtt`](govee2mqtt/) â Govee BLE lights â MQTT
- [`deconz`](deconz/) â Zigbee gateway (ConBee II)
- [`pihole`](pihole/) â Network-wide ad/DNS blocking
- [`unifi`](unifi/) â Ubiquiti UniFi Controller
- [`cloudflare-dns`](cloudflare-dns/) â Cloudflare DDNS CronJob
- [`ingress`](ingress/) â ingress-nginx + cert-manager ClusterIssuer
- [`metallb`](metallb/) â Bare-metal load balancer config
- [`pv_nfs`](pv_nfs/) â NFS persistent volume provisioner
- [`wordpress`](wordpress/) â WordPress + MariaDB
- [`ingress-nginx`](ingress-nginx/) â Cloudflare real IP forwarding config for ingress-nginx
---
## đ Installation â k3s
Edit `/boot/firmware/cmdline.txt` (Bookworm) or `/boot/cmdline.txt` (Bullseye) and append to the **single existing line**:
```
cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1
```
Then install k3s with Traefik and the built-in service LB disabled:
```
curl -sfL https://get.k3s.io | sh -s - --disable=traefik --disable=servicelb --write-kubeconfig-mode 644
```
---
## đ Installation â NFS Persistent Storage
Follow this tutorial to configure your Pi as an NFS server:
https://pimylifeup.com/raspberry-pi-nfs/
Then deploy the NFS provisioner in k3s:
```
cd pv_nfs
kubectl apply -f class.yaml
kubectl apply -f rbac.yaml
kubectl apply -f deployment.yaml
```
---
## đ Installation â NGINX Ingress
```
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.12.0/deploy/static/provider/cloud/deploy.yaml
```
---
## đ Installation â MetalLB Load Balancer
```
cd metallb
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.15.3/config/manifests/metallb-native.yaml
vi config.yaml # edit and set the IP address range reserved on your DHCP server
kubectl apply -f config.yaml
```
---
## đ Installation â HTTPS Ingress via cert-manager & Let's Encrypt
Below will install cert-manager **v1.19.4**, which is the latest version as of **25th February 2026**.
```
cd ingress
kubectl create namespace cert-manager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.19.4/cert-manager.yaml
vi letsencrypt.yaml # update your email address
kubectl apply -f letsencrypt.yaml
```
Remember to open ports 80 and 443 on your router and forward traffic to the MetalLB ingress IP.
---
## đ Installation â Applications
For each app, edit `pv.yaml` to set your NFS server IP and path, edit `secrets.yaml` to set credentials, then:
```
kubectl apply -f pv.yaml
kubectl apply -f secrets.yaml
kubectl apply -f deployment.yaml
kubectl apply -f svc.yaml
kubectl apply -f ingress.yaml # if applicable
```
See each app's `README.md` for specific instructions.
---
## đ Secrets Management
Each app has a `secrets.yaml` file excluded from git via `.gitignore`. Never commit real credentials. See each app folder for the specific secrets required.
---
## âď¸ Cloudflare DNS
All services are exposed via Cloudflare-proxied subdomains. DNS records are kept in sync automatically via the [`cloudflare-dns`](cloudflare-dns/) CronJob which runs every 20 minutes.
---
## âŹď¸ Upgrading k3s
```
curl -sfL https://get.k3s.io | sh -s - --disable=traefik --disable=servicelb --write-kubeconfig-mode 644
kubectl get nodes
```
Always check the [k3s release notes](https://github.com/k3s-io/k3s/releases) before upgrading.
---
Built with â and mild obsession by [Andrew Morty](https://mortylabs.com) đ´ó §ó ˘ó łó Łó ´ó ż