← Learn··Updated 31 May 2026·5 min read

Expose your homelab to the internet

Put your self-hosted services on a real domain with HTTPS, without exposing your home IP or opening a single port on your router. A VPS holds the public edge; a WireGuard tunnel reaches back into your homelab; Caddy terminates TLS and routes. The ordered reading list, and where it leads.

Networking
#networking
#wireguard
#caddy
#self-hosting
#vps
#ai-assisted

level:Intermediate

You built a homelab, or a k3s cluster, and everything works beautifully — on your own network. Then you try to reach it from a phone on mobile data, or share a service with a friend, and hit the wall every home self-hoster hits: your services are trapped behind your router. This series is about getting out of that trap properly — putting your services on a real domain, with real HTTPS, reachable from anywhere — without opening ports on your home router and without exposing your home IP address to the internet.

The trick is to stop trying to make your home network face the internet at all. Instead, a cheap public VPS holds the public-facing edge — it owns the domain, the open ports, and the TLS certificates — and a private WireGuard tunnel reaches from that VPS back into your homelab. Caddy on the VPS terminates HTTPS and forwards each request down the tunnel to the right internal service. Your home IP never appears in DNS; your router never forwards a port; the only thing the internet can see is one hardened VPS.

This is the capstone to the homelab and Kubernetes tracks. The Build a homelab on Debian and Kubernetes from scratch with k3s series get services running; this series gets them reachable, safely. You do not strictly need either of those first — the pattern works for any service on any home server — but the final part wires the edge specifically into a k3s cluster, closing the loop.

Who this is for

You are the right reader if any of these sound like you. You self-host something at home and want to reach it from outside without a clunky VPN client on every device. You are behind CGNAT or a dynamic IP and port-forwarding simply is not an option. You do not want your home IP address sitting in a public DNS record for anyone to scan. Or you have a k3s cluster and want it answering on a real domain with automatic certificates.

You do not need to be a network engineer. You should be comfortable in a Linux terminal and SSH, and have a server (or cluster) already running on your home network — if you do not, start with the homelab series first. Everything else — what a tunnel is, what a reverse proxy does, how DNS resolves — the series explains the first time it matters.

The shape of the series

The series opens with the reasoning: Why self-host behind a VPS lays out the problem (NAT, CGNAT, dynamic IPs, and why you should never put your home IP in public DNS) and compares the realistic ways to solve it — a raw WireGuard tunnel to a VPS, Cloudflare Tunnel, Tailscale Funnel, and tools like frp — so you understand the trade-offs before committing to the VPS-and-WireGuard build the rest of the series uses.

Then it builds the edge from the outside in. Buy a domain and point DNS gets you a name and the records pointing at your VPS. Provision a Hetzner VPS stands up and hardens the public host. WireGuard tunnel: VPS to homelab builds the private link between them. Caddy: reverse proxy and automatic HTTPS puts a TLS-terminating front door on the VPS and forwards the first real service down the tunnel.

The last two parts go deeper. Routing into k3s from the edge connects the edge to a cluster's ingress with a wildcard domain, so one VPS fronts every service you deploy. Hardening and operating a public edge covers the security posture and the day-two work — locking down the tunnel, rate-limiting, security headers, certificate renewal, and what to do when the VPS goes down.

flowchart TD
    A["1. Why self-host behind a VPS"] --> B["2. Buy a domain + point DNS"]
    B --> C["3. Provision a Hetzner VPS"]
    C --> D["4. WireGuard tunnel: VPS ↔ homelab"]
    D --> E["5. Caddy: reverse proxy + HTTPS"]
    E --> F["6. Routing into k3s from the edge"]
    F --> G["7. Hardening + operating the edge"]

Built from the outside in: decide the approach, get the name, stand up the public host, link it privately to home, route traffic, then lock it down.

The end state, in one picture: a request from anywhere on the internet hits your domain, resolves to the VPS, is terminated and routed by Caddy, travels the encrypted WireGuard tunnel into your homelab, and lands on the right service — all without a single open port on your home router.

flowchart LR
    U["Visitor"] -->|"https://app.you.dev"| DNS["DNS → VPS public IP"]
    DNS --> V["Hetzner VPS<br/><i>Caddy, TLS, :443</i>"]
    V -->|"WireGuard tunnel"| H["Homelab<br/><i>k3s / Docker, behind NAT</i>"]
    H --> S["Your service"]

The home network never faces the internet; the VPS is the only exposed surface.

Where it leads next

By the end you will have a repeatable pattern: any new service you self-host becomes publicly reachable by adding one DNS record and a few lines of Caddy config — no router changes, ever. That pairs naturally with the tracks that produce the services in the first place. If you have not built the backend yet, the homelab on Debian series takes you from a bare server to running containers, and Kubernetes from scratch with k3s does the same with a real cluster. This series is the front door for both.

A note on the building blocks, since the terms recur. A reverse proxy sits in front of your services and decides where each request goes; WireGuard is a modern, deliberately small VPN that builds the encrypted link between two machines; and the whole scheme leans on TLS certificates, which Caddy obtains and renews for you automatically. Where that background helps, the parts link out to it.

The reading order

Read these in order. Each links to the next, and the navigation at the bottom of every page offers previous and next.

  1. Why self-host behind a VPS — the NAT/CGNAT problem, why your home IP should never be public, and the approaches compared.
  2. Buy a domain and point DNS — choosing a registrar and pointing the right records at your VPS.
  3. Provision a Hetzner VPS — create, access, and harden the public host that holds the edge.
  4. WireGuard tunnel: VPS to homelab — build the encrypted private link between the VPS and your home server.
  5. Caddy: reverse proxy and automatic HTTPS — terminate TLS on the VPS and forward your first service down the tunnel.
  6. Routing into k3s from the edge — front an entire cluster with a wildcard domain and per-service hostnames.
  7. Hardening and operating a public edge — the security posture and the day-two operations.

A short close

💡 Tip — You can stop after part 5 and have a single service live on your domain with HTTPS — that alone is the whole win for many people. Parts 6 and 7 are for when you want to front a cluster and run the edge like production.

This is the part of self-hosting that finally makes it feel real: your own services, on your own domain, reachable from anywhere, with your home network still completely private. It is also the most security-sensitive thing in these tracks — you are putting a host on the public internet — so the series is deliberately careful about the order and the hardening. Start with Why self-host behind a VPS, and build it from the outside in.