pez-infra/docs/hosts/helsinki-a.md
Rasmus "Pez" Wejlgaard 0a357fc69a
Some checks failed
Terraform / Plan (push) Has been cancelled
Terraform / Apply (push) Has been cancelled
docs: catch up with the Cloudflare to Hetzner DNS move, fix secrets/terraform drift (#130)
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 20:59:23 +01:00

52 lines
2.6 KiB
Markdown

# 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.