mirror of
https://github.com/RWejlgaard/pez-infra.git
synced 2026-05-06 04:14:43 +00:00
110 lines
6.5 KiB
Markdown
110 lines
6.5 KiB
Markdown
# Architecture
|
|
|
|
## Overview
|
|
|
|
The infrastructure spans four physical locations connected by a Tailscale mesh network. All public traffic enters through a single Hetzner Cloud VPS (helsinki-a) running Caddy as a reverse proxy, which forwards requests over Tailscale to backend services running on physical servers in London and Copenhagen.
|
|
|
|
The setup is entirely self-hosted (with the exception of Hetzner Cloud VPSs and Cloudflare for DNS/CDN). Servers are old personal computers repurposed into server duty — cheaper than cloud, and I get a rack cabinet that doubles as a bedroom white noise machine.
|
|
|
|
## Network Topology
|
|
|
|
```
|
|
┌──────────────┐
|
|
│ Cloudflare │
|
|
│ DNS + CDN │
|
|
│ *.pez.sh │
|
|
└──────┬───────┘
|
|
│
|
|
│ HTTPS
|
|
│
|
|
┌────────────▼────────────┐
|
|
│ helsinki-a │
|
|
│ Hetzner Cloud VPS │
|
|
│ │
|
|
│ Caddy (reverse proxy) │
|
|
│ Authelia (SSO) │
|
|
│ Bitwarden │
|
|
│ LLDAP │
|
|
└────────────┬────────────┘
|
|
│
|
|
┌───────────────┼───────────────┐
|
|
│ Tailscale Mesh │
|
|
│ (WireGuard-based VPN) │
|
|
└───┬───────┬───────┬───────┬───┘
|
|
│ │ │ │
|
|
┌────────▼──┐ ┌──▼────────┐ ┌────▼───────┐ ┌──▼──────────┐
|
|
│ london-b │ │ london-a │ │nuremberg-a │ │copenhagen-a │
|
|
│ │ │ │ │ │ │ │
|
|
│ Storage │ │ Monitoring│ │ Mail │ │ Gaming │
|
|
│ Media │ │ Prometheus│ │ poste.io │ │ Minecraft │
|
|
│ Docker │ │ Grafana │ │ │ │ WoW/MaNGOS │
|
|
│ services │ │ │ │ │ │ │
|
|
│ (46T ZFS) │ │ (FreeBSD) │ │ (Alpine) │ │ (Ubuntu) │
|
|
└───────────┘ └───────────┘ └────────────┘ └─────────────┘
|
|
|
|
┌─────────────┐
|
|
│copenhagen-c │
|
|
│ (idle) │
|
|
└─────────────┘
|
|
```
|
|
|
|
## Traffic Flow
|
|
|
|
All public-facing services follow the same pattern:
|
|
|
|
```
|
|
User → Cloudflare (DNS + TLS) → helsinki-a (Caddy) → Backend (over Tailscale)
|
|
```
|
|
|
|
1. DNS for `*.pez.sh` is managed by Cloudflare (provisioned via Terraform)
|
|
2. Cloudflare proxies traffic to helsinki-a
|
|
3. Caddy on helsinki-a terminates TLS and routes to the correct backend
|
|
4. For protected services, Caddy calls Authelia first (`forward_auth`)
|
|
5. If authenticated (or no auth required), traffic is proxied over Tailscale to the backend
|
|
|
|
```
|
|
┌─────────────────────────────────────────────┐
|
|
│ helsinki-a (Caddy) │
|
|
│ │
|
|
radarr.pez.sh ──► │ forward_auth → Authelia ──► london-b:7878 │
|
|
│ │
|
|
jellyfin.pez.sh ─►│ (no auth) ───────────────► london-b:8096 │
|
|
│ │
|
|
grafana.pez.sh ──►│ forward_auth → Authelia ──► london-a:3000 │
|
|
│ │
|
|
auth.pez.sh ─────►│ (local) ────────────────► localhost:9091 │
|
|
└─────────────────────────────────────────────┘
|
|
```
|
|
|
|
## Auth Architecture
|
|
|
|
```
|
|
┌──────────┐
|
|
│ Caddy │
|
|
│ │
|
|
│ forward_ │
|
|
│ auth │
|
|
└────┬─────┘
|
|
│
|
|
┌────▼─────┐
|
|
│ Authelia │ auth.pez.sh
|
|
│ (SSO) │
|
|
└────┬─────┘
|
|
│
|
|
┌────▼─────┐
|
|
│ LLDAP │ User directory
|
|
│ │
|
|
└──────────┘
|
|
```
|
|
|
|
Authelia authenticates against LLDAP (both on helsinki-a). One place to manage users — add or remove someone in LDAP and it propagates to all protected services.
|
|
|
|
Services with their own auth (Bitwarden, Jellyfin, Plex, Nextcloud, Navidrome, Jellyseerr) are not behind Authelia.
|
|
|
|
## Design Principles
|
|
|
|
- **Self-hosted first.** Cloud VPSs only where it makes sense (public gateway, mail with clean IP reputation). Everything else runs on physical hardware I own.
|
|
- **Tailscale as the backbone.** No ports exposed on residential IPs. All inter-server communication goes over the mesh.
|
|
- **Ansible for everything.** If a server dies, reinstall the OS, install Tailscale, run Ansible. 30 minutes to full recovery.
|
|
- **Terraform for DNS.** All Cloudflare records are in code. No clicking around in dashboards.
|
|
- **Cattle, not pets (as much as possible).** The servers are technically pets — old hardware in specific locations — but the configs are cattle. Everything is reproducible from this repo.
|