Initial commit: PFI fleet inventory, stacks, tooling, and backup pipeline

Captures the full workspace state built up to this point:

  - CLAUDE.md + README.md describing conventions and the four-host fleet
    (ana-ml2, ana-docker, nh3-docker, esh-docker-vm).
  - Per-host notes under servers/<host>/ with ssh-target fallback files
    and latest system-details snapshots (two in-compose credential leaks
    scrubbed; the upstream compose files still need to move those to .env).
  - scripts/: server_inspect.sh (read-only remote diagnostic),
    refresh-server-info.sh (dir-driven discovery + snapshot capture with
    validation warnings), add-host.sh, sync-stacks.sh (pull
    compose/conf trees), deploy-stack.sh (push with per-file diff + prompt).
  - stacks/: canonical compose for backrest, beszel, dozzle, llama-swap,
    rest-server-ana, rest-server-nh3, vllm-qwen3, plus the retired
    infinity reference. All use the .env-driven + traefik-net + homepage
    label pattern.
  - configs/restic/ana-docker/: first resticprofile config + pre-backup
    hook (Synapse pg_dump, Seafile mysqldump, Vaultwarden SQLite); templates
    for the other three hosts to come.
  - docs/pfi/: general infrastructure reference carried over.
  - .gitignore excludes .env, stacks-mirror/, and assorted secret/state
    filenames to prevent re-leaks on later commits.
This commit is contained in:
vh
2026-04-20 14:29:48 -07:00
commit e376d0aec9
55 changed files with 9101 additions and 0 deletions
+76
View File
@@ -0,0 +1,76 @@
# esh-docker-vm
General-purpose Docker host at the **ESH home-lab site** (`esteban.net` / `10.0.0.0/8` space). VM, no GPU. Separate scope from the PFI colo work but tracked here because it's part of the same fleet.
## Network
- **LAN IP:** 10.0.50.45
- **FQDN:** `esh-vm-docker.esteban.net`
- **Subnet:** `10.0.50.0/24` (inferred from macvlan config)
- **SSH:** standard port 22
- **Traefik entrypoints:** 80/443 terminate here; DNS-01 challenge via AWS Route53; protected by CrowdSec Traefik plugin
## Hardware
- **CPU:** 16 vCPU (QEMU virtual — VM)
- **RAM:** 15.6 GB
- **GPUs:** none
- **Storage:** 250 GB root (ext4) + NFS mounts from `10.0.50.50`
- **OS:** Debian 12 (bookworm), kernel 6.1.x
- **Docker:** running (daemon socket at `/var/run/docker.sock`; also listens on `:2375`)
## Key paths
| Path | Purpose |
|------|---------|
| `/opt/docker/compose/<stack>/` | Compose files (also a git repo) |
| `/opt/docker/conf/<stack>/` | Config bind mounts |
| `/opt/docker/docker-bu/` | Legacy backup staging (ad-hoc) |
| `/mnt/compose` | NFS — `10.0.50.50:/mnt/compose` |
| `/mnt/backup` | NFS — `10.0.50.50:/mnt/backup` (volume-backup sidecars write here) |
| `/mnt/documents` | NFS — `10.0.50.50:/mnt/documents` (Paperless-ngx source) |
| `/mnt/books` | NFS — `10.0.50.50:/mnt/books` (Calibre library) |
## Running stacks
| Stack | Port(s) | Notes |
|-------|---------|-------|
| traefik | 80 / 443 / 8380 | Reverse proxy + TLS (AWS Route53 DNS-01); CrowdSec bouncer plugin |
| cloudflare-ddns-esh | — | Keeps the `esteban.net` record in sync with the dynamic WAN IP |
| adguard | 53 / 853 / 8080 / 8443 / 3000 / 784 | DNS + DoT for the ESH site |
| dockge | 5001 | Docker stack management UI |
| homepage | 5100 | Dashboard (`eshhome` / `eshhome.esteban.net`) |
| uptime-kuma | 3001 | Service uptime monitor |
| homeassistant | macvlan `10.0.50.46:8123` | Home automation (direct LAN IP via macvlan on `ens18`) |
| esphome | host net / 6052 | ESPHome firmware dashboard |
| mosquitto | 1883 | MQTT broker |
| calibre | 8082 / 8181 / 8281 | Ebook server |
| calibre-web | 8083 | Ebook web UI |
| paperless-ngx (+ redis broker + volume-backup sidecar) | 8200 | Document archive; Postgres on `10.0.50.60:5432` |
| pgadmin (+ volume-backup sidecar) | 5050 | Postgres admin UI |
| drawio | 8087 / 8447 | Diagram editor |
| dozzle-agent | 7007 | Log agent; feeds ana-docker's Dozzle hub |
| beszel-esh-vm-docker (agent) | 45876 | Metrics agent; feeds ana-docker's Beszel hub |
| portainer (+ portainer_agent) | 9443 / 8000 / 9001 | Container management UI (ad-hoc, no compose dir under `/opt/docker/compose/`) |
## Refresh state
```bash
scripts/refresh-server-info.sh esh-docker-vm
```
Latest snapshot: `system-details.txt` (regenerate as needed).
## Cross-site monitoring
Like `nh3-docker`, this host runs **Dozzle** and **Beszel** agents that report back to the hubs on `ana-docker`, so container logs and metrics show up alongside PFI hosts in the shared dashboards.
## Notes
- **Macvlan for Home Assistant** — the HA container gets its own LAN IP (`10.0.50.46`) via a macvlan network on `ens18`, avoiding NAT so multicast/mDNS for HA discovery works cleanly.
- **External Postgres** — Paperless-ngx connects to a DB running elsewhere (`10.0.50.60:5432`), not a sidecar. Paperless creds in that compose file currently look like defaults; rotate before exposing.
- **Volume backups already in place** — `paperless-ngx` and `pgadmin` include `offen/docker-volume-backup:latest` sidecars that tar named volumes to `/mnt/backup/docker/esh-vm-docker/<stack>/`. When the fleet-wide restic plan lands, decide whether to subsume these or leave the per-stack sidecars alone.
## Placement rule
Home-lab workloads for the ESH site go here. Not part of the PFI colo topology.