pez-infra/docs/hosts/helsinki-a.md
Rasmus Wejlgaard 361133ec7e docs: catch up with the Cloudflare to Hetzner DNS move, fix secrets/terraform drift
The docs still described Cloudflare as DNS + CDN in front of helsinki-a,
but that was dropped in #90 - pez.sh lives on Hetzner DNS via Terraform
now and records point straight at the origin. Updated README,
architecture, networking, getting-started and the nuremberg-a host doc
to match, and noted that pez.solutions still resolves via Cloudflare
outside Terraform.

Also fixed while I was in there:
- terraform/README: PagerDuty provider is ~> 3.32 (table said ~> 2.2),
  and the B2 secret keys are backblaze_keyID/backblaze_applicationKey
- secrets docs: group_vars secrets file is .enc.yaml, dropped the
  FreeBSD install steps, the long-gone .sops.yaml placeholder note and
  the ANSIBLE_VAULT_PASS migration note, swapped the cloudflare_record
  example for hcloud
- getting-started referenced ansible/scripts/sops-setup.sh which
  doesn't exist
- added naveen.pez.sh to the subdomain tables and a note about the
  DNS-only records (mail, minecraft, wow, public)
2026-06-10 19:35:53 +01:00

2.6 KiB

helsinki-a

Public-facing traffic gateway. Everything exposed to the internet goes through this box.

Overview

Location Hetzner Cloud (Helsinki)
OS Debian 13 (Trixie)
Tailscale IP 100.67.6.27
Role Reverse proxy, SSO, Bitwarden, Forgejo
Provider Hetzner Cloud VPS

What it does

This is the front door. All public subdomains under pez.sh and pez.solutions terminate here via Caddy, which proxies traffic to the appropriate backend over Tailscale.

It also runs the auth stack — Authelia for SSO and LLDAP as Authelia's user backend. Having auth on the same box as the proxy keeps latency low for the forward_auth check.

Bitwarden (Vaultwarden) and Forgejo also live here. Both expose their own login and don't go through Authelia. Bitwarden is on helsinki-a for availability — password management needs to be reachable even if the London servers are having a moment. Forgejo is colocated for the same reason and to keep Git access independent of home internet.

Services

Service Port Deployment Notes
Caddy 80, 443 Native (apt + systemd) Reverse proxy + TLS termination. Config at /etc/caddy/Caddyfile
Authelia 9091 Docker SSO, accessible at auth.pez.sh
Authelia MariaDB (internal) Docker Authelia session/state
LLDAP 3890, 17170 Docker User directory for Authelia (UI at ldap.pez.sh)
Bitwarden (Vaultwarden) 8443, 8080 Docker bitwarden.pez.sh, own auth
Bitwarden MariaDB (internal) Docker Backing DB
Forgejo 3000 (HTTP), 2222 (SSH) Docker git.pez.sh, own auth; SSH on git.pez.sh:2222

Caddy is the only service installed natively — it needs to bind 80/443 directly and there's no benefit to wrapping it in Docker on a single-purpose proxy host. Everything else runs as Docker Compose stacks under /opt/docker/<service>/ (managed by the docker_services Ansible role from ansible/services/<service>/docker-compose.yml).

Static sites

Caddy also serves static content from /srv/:

Path URL Auth
/srv/status status.pez.sh
/srv/apps apps.pez.sh, apps.pez.solutions Authelia
/srv/pez.sh pez.sh
/srv/pez.solutions pez.solutions
/srv/pez-signup signup.pez.solutions
/srv/naveen naveen.pez.sh

Why Hetzner Cloud

Public-facing services need a stable public IP and good uptime. Residential IPs are dynamic and unreliable for this purpose. Hetzner Cloud is cheap, reliable, and has good European connectivity.