Homelab - Day 3 - The first software deployment

Posted on Fri 28 February 2025 in homelab

Aims

The goal for today was to get my first piece of software running on the cluster, ensuring that:

  • It leveraged the NAS for storage.
  • It was accessible externally via Traefik.
  • The process was repeatable for future deployments.

I chose the Unifi Management Console as my first self-hosted application. Once migrated, I could wipe my Raspberry Pi 4, which was previously running the console, and add it as a worker node to the cluster.


What I Did

NFS Storage Setup

  • I needed NFS storage to persist Unifi’s data.
  • After trying multiple providers, I settled on the nfs-subdir-external-provisioner Helm chart.
  • I pointed it at my NAS server to handle persistent storage.

Persistent Volume & Claims

  • Configuring Persistent Volumes (PVs) and Persistent Volume Claims (PVCs) took some effort.
  • Eventually, I got them working with my NAS-hosted NFS.

Ingress & Networking Challenges

  • Since K3s includes Traefik by default, I wanted to leverage its built-in ingress controller.
  • Initially, I attempted to use IngressRoutes, but Unifi’s self-signed TLS certificate caused issues.
  • After much debugging, I realised I needed IngressRouteTCP with TLS passthrough.
  • The final working configuration looked like this:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
  name: unifi-ingress-tcp
  namespace: unifi
spec:
  entryPoints:
    - websecure
  routes:
    - match: HostSNI(`example.com`)  # SNI-based routing required
      services:
        - name: unifi-gui
          port: 8443
  tls:
    passthrough: true  # Required to let Unifi handle TLS

Lessons Learned

  • NFS Setup Took Iterations – The nfs-subdir-external-provisioner was the best option for easy NAS integration.
  • Ingress Troubles – K3s’ built-in Traefik works well, but TLS handling is tricky with self-signed certs.
  • IngressRoute vs IngressRouteTCP – If an app manages its own TLS, use IngressRouteTCP with passthrough instead of a standard IngressRoute.

Final Thoughts

Now that I’ve got my first app running, I expect future deployments to be faster and more repeatable. Next, I need to figure out subdomains and path-based routing for managing multiple applications—but that’s a problem for another day!