mirror of
https://github.com/RWejlgaard/pez-infra.git
synced 2026-05-06 04:14:43 +00:00
Mono-repo for my server stack
* phase 1 - add all the records to both providers to A/B test * dkim fix |
||
|---|---|---|
| .github/workflows | ||
| ansible | ||
| docs | ||
| terraform | ||
| .gitignore | ||
| .sops.yaml | ||
| Makefile | ||
| README.md | ||
pez-infra
Infrastructure-as-code monorepo for managing my homelab and cloud server fleet. It contains everything needed to rebuild, configure, and maintain the entire infrastructure from scratch — including server provisioning, service deployment, DNS, monitoring, and secrets management.
What's in this repo
- Ansible — Playbooks, roles, and inventory for configuring servers, deploying Docker-based services, and managing dotfiles
- Terraform — OpenTofu/Terraform configs for cloud resources (Cloudflare DNS, Hetzner servers)
- Services — Docker Compose definitions and config files for each self-hosted service
- Documentation — Architecture decisions, networking topology, and operational guides
Architecture Overview
graph TD
CF[Cloudflare<br/>DNS + CDN] --> HEL[helsinki-a<br/>Caddy proxy<br/><i>Hetzner Cloud</i>]
HEL --> TS{Tailscale mesh}
TS --> LB[london-b<br/>Storage, Docker services]
TS --> LA[london-a<br/>Monitoring<br/>Prometheus, Grafana]
TS --> CA[copenhagen-a<br/>Gaming<br/>Minecraft, WoW MaNGOS]
TS --> NUR[nuremberg-a<br/>Mail, poste.io]
TS --> CC[copenhagen-c<br/>idle]
Traffic enters via Cloudflare DNS, hits a Caddy reverse proxy on a Hetzner cloud instance, and is forwarded to backend services running on various hosts connected over a Tailscale mesh network. Authentication is handled by Authelia with an LLDAP backend.
Hosts
| Host | Location | OS | Role |
|---|---|---|---|
| helsinki-a | Hetzner Cloud | Linux | Reverse proxy (Caddy), main traffic gateway |
| london-b | London | Linux | Primary storage (ZFS), Docker services |
| london-a | London | FreeBSD | Monitoring (Prometheus, Grafana) |
| nuremberg-a | Hetzner Cloud | Alpine Linux | Mail server (poste.io) |
| copenhagen-a | Copenhagen | Linux | Gaming servers (Minecraft, WoW/MaNGOS) |
| copenhagen-c | Copenhagen | Linux | Idle/available |
Directory Structure
├── ansible/ # Ansible playbooks, roles, inventory, and all managed files
│ ├── roles/ # Ansible roles (caddy, docker, dotfiles, etc.)
│ ├── services/ # Docker Compose definitions and service configs
│ ├── dotfiles/ # Shell config (fish, nvim, tmux, git, etc.)
│ └── scripts/ # Utility and maintenance scripts
├── terraform/ # Terraform/OpenTofu for Cloudflare DNS, Hetzner servers
└── docs/ # Architecture, networking, services, and monitoring docs
Getting Started
Prerequisites
- SSH access to hosts via Tailscale
ansiblefor configuration managementtofu(OpenTofu) orterraformfor infrastructure provisioning
Usage
- Clone:
git clone git@github.com:RWejlgaard/pez-infra.git - Services: Each service has its own directory under
ansible/services/with adocker-compose.ymland config files - Deploy: Ansible playbooks in
ansible/handle deployment (see individual playbook docs) - Infrastructure: Terraform configs in
terraform/manage DNS and cloud resources
Secrets
Secrets are encrypted in-repo using SOPS + age. Encrypted files use .enc. in their extension (e.g. secrets.enc.yml). See Secrets Management for full setup and usage instructions.
Documentation
Detailed documentation lives in docs/:
- Architecture — Network topology, traffic flow, design principles
- Networking — Tailscale mesh, DNS flow, physical networking
- Services — Complete service map with ports, auth, and deployment info
- Monitoring — Prometheus, Grafana, exporters, status page
- Getting Started — How to work with this repo