§12.6 ASCII rack diagram side-by-side, §12.7 Mermaid equivalent for
GitHub-rendered viewing. Standalone copy at docs/network/rack-layout.md
so the visual is reachable without scrolling through the full migration
guide.
§11 documents the explicit decision to defer 2.5GbE at the desk, the
constraints that block a quick fix (NUC 1G NIC, Lite-8 1G ports, CRS309
has no 2.5G RJ45), and two upgrade paths for when it's revisited.
§12 captures the current 15U Linkbasic rack contents, a recommended
target layout that puts the patch panel between Lite-8 and CRS309 for
short patches, uses rear-routed DACs through a brush panel so MS-A2 and
UNAS Pro don't have to sit adjacent to the CRS309, and pairs MS-A2 with
the Wyse 5070 on a shared 2U vented shelf. Also includes a physical
migration order, cable-management discipline, and a power-draw delta.
Shopping list renumbered §11 → §13.
- Add §2 "Current Topology" with Lite-8 port map and mermaid diagram so
readers can see what's changing, not just the destination.
- Retire the TP-Link TL-SG1016DE office switch; office devices fold back
onto Lite-8 ports 6/7/8 (U3425we monitor, Wyse 5070, optional NUC drop).
- Pin Wyse 5070 as the dedicated Home Assistant host (HA + Mosquitto +
Z2M stay on it; only the uplink moves).
- Remove Node-RED from the service map — being decommissioned.
- Add §6 "Service Placement" mapping every Docker stack from the repo to
its target host, plus UNAS Pro NFS share layout.
- New gotchas: Lite-8 port budget, Z2M-over-TCP, Emby VAAPI on MS-A2,
Beszel host networking, KVM pass-through caveat.
DS920+ is fully retired (no backup role). Intel NUC repurposed as
desktop replacing Mac mini. SMLIGHT SLZB-06U Zigbee coordinator is
PoE-powered from the Lite-8, so it's added to the PoE budget table —
new total ~30-35 W of 52 W, but all 4 PoE+ ports are now used.
https://claude.ai/code/session_011ttbGhvdo5k2GTn69kceA2
Replace UDM Pro / USW-Aggregation / UGREEN DXP8800 Plus / Intel NUC
build with MS-A2 (Proxmox + pfSense VM), MikroTik CRS309-1G-8S+IN,
and UniFi NAS Pro 2U. Power CRS309 via PoE-in from Lite-8, keep
1G SFP-to-RJ45 for Lite-8 uplink (thermal), and host the UniFi
Network Application on the NAS Pro. Mermaid diagram switched to
vertical layout.
https://claude.ai/code/session_011ttbGhvdo5k2GTn69kceA2
head -1 always returned the first (empty) match when a key existed with
an empty value in .env, causing auto-generated secrets like
NODE_RED_CREDENTIAL_SECRET to be ignored during substitution.
- Replace GENERATE placeholders with actual pan_id/network_key values
- Add known devices with friendly names to template
- Setup script now skips zigbee2mqtt config copy if file already exists,
preventing configuration-adapter mismatch on redeploy
The compose file is generated one level above the repo, so a relative
path like ./docker-compose-files/node-red resolves to the wrong directory.
The setup script now injects the absolute path to the Dockerfile directory
as NODE_RED_BUILD_CONTEXT at generation time.
The gitignore pattern for docker-compose-files excluded all files except
templates and config dirs — Dockerfile was silently ignored. Added
!docker-compose-files/**/Dockerfile exception so custom images are tracked.
- Custom Dockerfile installs node-red-contrib-home-assistant-websocket
into the base image (not /data) to avoid volume mount conflicts
- Joins ha-network so Node-RED reaches homeassistant:8123 by container name
- HA_URL and HA_TOKEN passed as env vars so the token stays out of flow files;
use $(HA_URL) and $(HA_TOKEN) when configuring the server node in the editor
- credentialSecret substituted at setup time via setup-node-red.sh, consistent
with the rest of the project; auto-generates NODE_RED_CREDENTIAL_SECRET if absent
- appdata/node-red owned by uid 1000 to match the container user
- README updated with stack docs, env vars, and deployment steps
- Remove Synology-specific comment, labels, and version field from beszel-agent template
- Use container names (mqtt, zigbee2mqtt) instead of localhost in healthchecks
Caddyfile
- Add Home Automation Stack section with ha. and z2m. subdomains
proxying to the mini PC on the IoT VLAN (CADDY_IOT_PREFIX.X)
- Comment references Caddy trusted proxy requirement handled by
ha_configuration.yaml
homeassistant/config/ha_configuration.yaml (new)
- Minimal HA configuration.yaml template with http.trusted_proxies
set to CADDY_OFFICE_PREFIX.5 (Caddy's static Office VLAN IP per
network docs) — rendered via substitute_env.sh before first run
Stale reference cleanup
- homeassistant/template.yaml: remove CADDY_HA_HOST from comment,
add ha_configuration.yaml to pre-run steps
- homeassistant/config/zigbee2mqtt_configuration.yaml: replace
{{DOCKERCONFDIR}} path comment with ./appdata/ relative path
- README.md: replace $DOCKERCONFDIR in workflow example and stack
config template paths with ./appdata/; relabel DOCKERCONFDIR env
var as arr-stack only
Generated files (docker-compose.*.yml) produced by substitute_env.sh
are environment-specific and should never be committed. Adding the
pattern prevents them from showing as staged after generation.
Fixes .gitignore to track the new folder-per-stack layout introduced in
the previous refactor commit. The old rule only whitelisted *_template.*
filenames; templates named template.yaml and config/ files were silently
ignored, leaving the repository missing most of its content.
.gitignore
- Whitelist docker-compose-files/**/template.* so the canonical
template.yaml / template.yml naming is tracked
- Whitelist docker-compose-files/**/config/** so per-stack config
templates (mosquitto.conf, zigbee2mqtt_configuration.yaml, etc.)
are tracked alongside their compose template
New stack templates (all migrated from *_template.yaml flat files)
- arr-stack/template.yaml
- beszel-agent/template.yaml
- gramps-web/template.yaml
- postgres/template.yaml — volumes switched from {{DOCKERCONFDIR}} to
relative ./appdata/ paths (DOCKERCONFDIR reserved for arr-stack only)
- socket-proxy/template.yaml
- technitium/template.yaml
- vault/template.yaml — same DOCKERCONFDIR → ./appdata/ migration
New homeassistant stack
- homeassistant/template.yaml — Home Assistant + Eclipse Mosquitto 2.x +
Zigbee2MQTT on a shared bridge network (ha-network) so all services
are reachable by container name (mqtt:1883, zigbee2mqtt:8080)
- homeassistant/config/mosquitto.conf — Mosquitto 2.x config with
explicit listener declarations (required since 2.0), persistence, and
WebSocket listener on 9001
- homeassistant/config/zigbee2mqtt_configuration.yaml — Zigbee2MQTT 2.x
config for SMLIGHT SLZB-06U over PoE+ (TCP socket via {{SLZB06_HOST}}:6638,
adapter: ember for Silicon Labs EFR32, MQTT via container name mqtt:1883)