Homelab · online

A homelab with no open ports.

Everything on this domain runs on hardware I own: a two-node Proxmox cluster and a Kubernetes cluster at home, plus one small cloud node at the edge. Public traffic never touches the house directly. It lands on the edge node, crosses an outbound-only tunnel, and is checked by single sign-on before any service sees the request.

20+
Services running
Git, K8s, media, AI, vault, metrics
0
Inbound ports at home
Tunnels dial out, never in
3
Nodes
2 Proxmox hypervisors + 1 cloud edge
1
Source of truth
Config in Git, applied by ArgoCD + Ansible

How a request travels

Architecture

Four hops. Each one has a single job, and each one can refuse the request. The home network is never addressable from the internet. A second set of names exists for internal use only — those resolve on the home DNS server and simply do not exist on the public internet.

PUBLIC INTERNET CLOUD EDGE · 1 NODE HOME NETWORK · PRIVATE Visitor https://bp31app.com Cloudflare DNS · tunnel ingress Single sign-on TLS · identity · policy only open ports: 80/443 Proxmox cluster 2 nodes · LXC + VMs K3s cluster GitOps · block storage Git · automation Media · AI · vault Metrics · logs · alerts Databases · routing Tunnels are dialled OUTBOUND from home, so the router needs no port forward and the house has no public address.
The edge node holds the only public address. If it disappears, the homelab is simply unreachable rather than exposed.

What is actually running

The stack

Chosen to be boring, reproducible, and recoverable from a backup and a config file. Service hostnames are deliberately not published here.

Edge

Tunnel ingress

Public names arrive at the cloud node through outbound-only tunnels. Nothing at home listens on a public address, and certificates are issued automatically.

PangolinCloudflare TunnelLet's Encrypt
Identity

Single sign-on

One login decides access for every private service, in front of the application instead of inside it. Revoking a person is one change in one place.

Authentik
auth required
Virtualisation

Proxmox cluster

Two hypervisor nodes run the lab: light services as containers, anything that needs its own kernel as a virtual machine. Workloads move between nodes.

Proxmox VELXCKVM
Orchestration

Kubernetes

A K3s cluster on its own network runs the workloads that benefit from scheduling and replicated storage. Desired state lives in Git, not in my head.

K3sArgoCDLonghorn
Network

Routing & DNS

A software router handles segmentation between the home, lab, and management networks. Internal names resolve only on the local DNS server, with ad blocking for the whole house.

VyOSTraefikPi-hole
Code

Self-hosted Git

Private repositories and the configuration that defines this lab, kept on the lab itself. The repo is the source of truth for every box above.

Gitea
Automation

Config & workflows

Hosts are configured by playbooks rather than by hand, run from a web UI with a history. Event-driven workflows glue the rest together.

AnsibleSemaphoren8n
Observability

Metrics, logs, alerts

Dashboards for metrics, searchable logs, external uptime checks, and push notifications — so a failure is noticed before anyone reports it.

GrafanaLokiUptime Kumantfy
Secrets

Password vault

Credentials stay on hardware I control, end-to-end encrypted, reachable only through the authenticated edge.

Vaultwarden
AI

Local models & agents

Language models run on lab hardware with a chat front end, plus a messaging assistant that answers from my own data. Prompts do not leave the house.

OllamaOpen WebUIPaperclip
Media & data

Library and databases

Media streaming for the household and a shared Postgres instance for the services that need real storage, both backed up on a schedule.

JellyfinPostgreSQL
Practice

A lab inside the lab

A throwaway Kubernetes cluster for certification practice, built to be broken and rebuilt without touching anything that matters.

KubernetesCKA

Why it is built this way

Operating principles

The rules that decide what gets added and what gets turned off.

  1. No inbound holesThe home router forwards nothing. The tunnel is dialled outward, so there is no port to find and no address to scan.
  2. Authenticate at the edgeAccess is decided once, in front of every service, instead of trusting each application's own login screen.
  3. The repo is the truthHosts are built by playbooks and clusters are reconciled from Git. If a change only exists on a machine, it does not exist.
  4. Split the networkHome, lab, and management traffic sit on separate segments, so a compromised toy cannot reach a database.
  5. Backups decide the designIf a service cannot be restored from a backup and a config file, it is not finished.
  6. Quiet by defaultInternal hostnames are not advertised. Discovery is not a security control, but there is no reason to help.
  7. Built to be explainedRunning it is only half the exercise. Being able to draw it on a whiteboard is the other half.