ADR 0056 made `acme-ca` a requirement of route-proxy, and step-ca is what answers it. A scenario that does not stock the image cannot run the CA, the proxy does not resolve, and every routed module on the mesh goes with it. This was carried as an uncommitted edit through the first ADR 0056 raise. Kept, because it is right, and committed, because a fix that lives in somebody's working tree is a fix the next raise does not have.
195 lines
8.2 KiB
YAML
195 lines
8.2 KiB
YAML
# The FULL mesh in its REAL production shape: two segments, one access point, one overlay.
|
|
#
|
|
# This is the first multi-segment whole-mesh bed. The earlier flat whole-mesh-full sat every node
|
|
# on one public segment with a SEPARATE `anchor` carrying the substrate. Production is not flat, and
|
|
# there is no separate anchor: `novox` IS the anchor. It sits on the routable `hosting` segment,
|
|
# runs the substrate (store, broker, control) AND its own service set AND is the overlay hub and the
|
|
# public ingress. `ace`, `shanks` and `g14` sit on the household `home` segment BEHIND a NAT gateway
|
|
# — the access point — reachable from the outside only through what they dial out to.
|
|
#
|
|
# hosting (public, routable) home (private, behind the access point)
|
|
# novox 192.0.2.20 ── anchor ace 192.168.1.10 home server, media/IoT set
|
|
# substrate + novox set shanks 192.168.1.20 workstation (light)
|
|
# overlay hub, ingress g14 192.168.1.30 workstation (light)
|
|
#
|
|
# The `home` gateway masquerades v4 outbound and forwards inbound (an ordinary household router).
|
|
# Home nodes reach novox's public 192.0.2.20 by dialling OUT through it: the substrate broker (5671),
|
|
# the registry, and — the thing this bed exists to prove — the WireGuard overlay hub (51820/udp).
|
|
# The hub keepalive holds the NAT hole open so the tunnel, once formed, stays up. novox cannot
|
|
# initiate to a home node at all; every home↔novox path is either the overlay or a forwarded port.
|
|
#
|
|
# THE UNPROVEN THING (what the flat beds never tested): does the overlay tunnel FORM across the
|
|
# access point — a home node dialling novox's public hub endpoint, the handshake completing through
|
|
# the gateway's masquerade? The driving test verifies the WireGuard handshake and cross-segment
|
|
# reachability over the overlay explicitly, and reports form-vs-break as its headline.
|
|
#
|
|
# Substrate-on-novox collides on two host ports the separate-anchor beds never hit: the substrate
|
|
# store binds 127.0.0.1:5432 and novox's postgres provider publishes 5432; the substrate broker binds
|
|
# 5671 + 127.0.0.1:5672 and novox's lavinmq provider publishes 5672. The driving test REMAPS those two
|
|
# provider host publishes off the substrate's ports (consumers reach the providers over the mesh
|
|
# network on the container port, so the host side is free to move). Reported as a topology finding.
|
|
#
|
|
# MESH_LAB_HOST_BINARY=.../mesh-host MESH_LAB_BUNDLE=.../examples/substrate-first-node.lock
|
|
# The images are the UNION of the novox set (feat/novox-conversions @ 431310f: the slug + roundcube
|
|
# fixes, so only-office/de-spiegel/amqp-email-forwarder now resolve) and the ace media/home set. Every
|
|
# one is already built/pulled by the per-server bed prerequisites.
|
|
scenario: whole-mesh-full
|
|
|
|
segments:
|
|
# The routable segment. novox lives here; the lab raises the image registry here too (a public
|
|
# IPv4 segment is what serves the images), and the overlay hub endpoint is a public address here.
|
|
hosting:
|
|
kind: public
|
|
cidr: [192.0.2.0/24]
|
|
|
|
# The household segment behind the access point. Its gateway is an ordinary home router: it
|
|
# masquerades v4 outbound, forwards inbound, and expires idle mappings after two minutes — which
|
|
# is exactly the NAT hole a WireGuard keepalive has to hold open.
|
|
home:
|
|
kind: private
|
|
cidr: [192.168.1.0/24]
|
|
gateway:
|
|
to: hosting
|
|
address: [192.0.2.50] # what the world sees the household as
|
|
nat: [v4]
|
|
forwardable: true
|
|
mapping_ttl: 120s
|
|
|
|
machines:
|
|
# The anchor: substrate (store, broker, control) + the whole novox service set + overlay hub +
|
|
# public ingress. Bigger than the flat bed's novox, because it now carries the substrate too.
|
|
novox:
|
|
at: { segment: hosting, address: [192.0.2.20] }
|
|
inbound: allow
|
|
memory: 24GiB
|
|
cpus: 8
|
|
disk: 130GiB
|
|
|
|
# The home server: the whole ace media/home set — 24 modules, ~50 containers, several heavy
|
|
# (Plex, Home Assistant, Letta, Baserow, the UniFi JVM, mssql). Behind the gateway.
|
|
ace:
|
|
at: { segment: home, address: [192.168.1.10] }
|
|
inbound: allow
|
|
memory: 18GiB
|
|
cpus: 6
|
|
disk: 120GiB
|
|
|
|
# Two workstations on the same home LAN. Light on purpose: they enrol, join the overlay, and run
|
|
# one small module (portainer) so a real module converges on each without heavy load. Same-LAN
|
|
# nodes with no overlay endpoint of their own hairpin the hub rather than peering directly, which
|
|
# is the normal case and is fine.
|
|
shanks:
|
|
at: { segment: home, address: [192.168.1.20] }
|
|
inbound: allow
|
|
memory: 3GiB
|
|
cpus: 2
|
|
disk: 30GiB
|
|
g14:
|
|
at: { segment: home, address: [192.168.1.30] }
|
|
inbound: allow
|
|
memory: 3GiB
|
|
cpus: 2
|
|
disk: 30GiB
|
|
|
|
images:
|
|
# --- substrate + shared (novox & ace both run postgres/redis/mssql/portainer) ---
|
|
- postgres:17-alpine
|
|
- cloudamqp/lavinmq:latest
|
|
- mesh-control:development
|
|
- redis:7-alpine
|
|
- mcr.microsoft.com/mssql/server:2022-latest
|
|
- portainer/portainer-ce:latest
|
|
# --- novox server images ---
|
|
- minio/minio:latest
|
|
- mongo:7
|
|
- quay.io/keycloak/keycloak:mesh
|
|
- gitea/gitea:1.22
|
|
- nextcloud:stable
|
|
- ghcr.io/umami-software/umami:postgresql-latest
|
|
- alpine:latest
|
|
- verdaccio/verdaccio:6
|
|
- registry:2
|
|
- registry-api.novox.be/novox/invoicing-app:latest
|
|
- registry-api.novox.be/novox/invoicing-api:latest
|
|
- onlyoffice/documentserver:mesh
|
|
- registry-api.novox.be/novox/de-spiegel:latest
|
|
- registry-api.novox.be/novox/www:latest
|
|
- registry-api.novox.be/novox/amqp-email-forwarder:latest
|
|
- registry-api.novox.be/novox/photos-server:latest
|
|
- registry-api.novox.be/novox/photos-admin-client:latest
|
|
- registry-api.novox.be/novox/photos-client:latest
|
|
# The full Mailu 1.9 stack (mailu-redis reuses redis:7-alpine above).
|
|
- ghcr.io/mailu/unbound:1.9
|
|
- ghcr.io/mailu/admin:1.9
|
|
- ghcr.io/mailu/dovecot:1.9
|
|
- ghcr.io/mailu/postfix:1.9
|
|
- ghcr.io/mailu/rspamd:1.9
|
|
- ghcr.io/mailu/clamav:1.9
|
|
- ghcr.io/mailu/roundcube:1.9
|
|
- ghcr.io/mailu/radicale:1.9
|
|
- ghcr.io/mailu/fetchmail:1.9
|
|
- ghcr.io/mailu/nginx:1.9
|
|
# --- ace server images ---
|
|
- lscr.io/linuxserver/sonarr:mesh
|
|
- lscr.io/linuxserver/radarr:mesh
|
|
- lscr.io/linuxserver/lidarr:mesh
|
|
- lscr.io/linuxserver/bazarr:mesh
|
|
- lscr.io/linuxserver/nzbget:mesh
|
|
- lscr.io/linuxserver/qbittorrent:mesh
|
|
- lscr.io/linuxserver/jackett:mesh
|
|
- lscr.io/linuxserver/ombi:mesh
|
|
- lscr.io/linuxserver/tautulli:mesh
|
|
- lscr.io/linuxserver/unifi-controller:mesh
|
|
- plexinc/pms-docker:mesh
|
|
- ghcr.io/pennydreadful/bookshelf:mesh
|
|
- ghcr.io/home-assistant/home-assistant:mesh
|
|
- eclipse-mosquitto:mesh
|
|
- influxdb:mesh
|
|
- grafana/grafana:mesh
|
|
- baserow/baserow:mesh
|
|
- letta/letta:mesh
|
|
- nodered/node-red:mesh
|
|
- searxng/searxng:mesh
|
|
- valkey/valkey:mesh
|
|
# --- per-module runtimes (union) ---
|
|
- mesh-runtime-postgres:development
|
|
- mesh-runtime-redis:development
|
|
- mesh-runtime-mssql:development
|
|
- mesh-runtime-portainer:development
|
|
- mesh-runtime-minio:development
|
|
- mesh-runtime-mongodb:development
|
|
- mesh-runtime-lavinmq:development
|
|
- mesh-runtime-keycloak:development
|
|
- mesh-runtime-gitea:development
|
|
- mesh-runtime-nextcloud:development
|
|
- mesh-runtime-umami:development
|
|
- mesh-runtime-verdaccio:development
|
|
- mesh-runtime-mailu:development
|
|
- mesh-route-proxy:development
|
|
# ADR 0056: the internal ACME authority. route-proxy now REQUIRES an `acme-ca`, so a bed that does
|
|
# not serve this image has an unresolvable proxy — and with it every routed module on the mesh.
|
|
- smallstep/step-ca:latest
|
|
- mesh-runtime-sonarr:development
|
|
- mesh-runtime-radarr:development
|
|
- mesh-runtime-lidarr:development
|
|
- mesh-runtime-plex:development
|
|
- mesh-runtime-bazarr:development
|
|
- mesh-runtime-nzbget:development
|
|
- mesh-runtime-qbittorrent:development
|
|
- mesh-runtime-jackett:development
|
|
- mesh-runtime-ombi:development
|
|
- mesh-runtime-tautulli:development
|
|
- mesh-runtime-bookshelf:development
|
|
- mesh-runtime-home-assistant:development
|
|
- mesh-runtime-mosquitto:development
|
|
- mesh-runtime-influxdb:development
|
|
- mesh-runtime-grafana:development
|
|
- mesh-runtime-baserow:development
|
|
- mesh-runtime-letta:development
|
|
- mesh-runtime-nodered:development
|
|
- mesh-runtime-searxng:development
|
|
- mesh-runtime-unifi:development
|
|
|
|
place:
|
|
all: [host, runtime]
|