28 KiB
Homelab Network Overhaul — Status & Decisions
Living document. Update checkboxes and tables as things change instead of re-deriving this from scratch each time.
Location: Linz, Austria. ISP: LIWEST (cable). Modem: Technicolor CGA4233-EU.
Current TODO
See todo.md for the live checklist. Quick status (as of 2026-10-04): bridge mode, controller adoption, firmware update, VLANs, ACLs, WireGuard VPN + INWX DynDNS, the SG2016P switch, all three SSIDs, NAS on Servers with QuickConnect disabled (both users' Synology apps on local login), the first Hyper Backup run, and the living-room EAP650 + ES205GP are all done. The Dell OptiPlex homeserver is up (homeserver.md): Omada controller migrated there, Pi-hole + NPM + Home Assistant running, all web UIs on HTTPS via a Let's Encrypt wildcard for *.home.staffenberger.at; switches/APs moved to Management VLAN 99, PC to Trusted, Default emptied. Next: switch DHCP DNS to the new Pi-hole and turn off the NAS one, tighten the ACLs, off-box backups of the OptiPlex, Hyper Backup test restore, office AP ceiling mount + Wi-Fi re-measure.
Hardware decisions
Network core
| Item | Model | Status |
|---|---|---|
| Router | TP-Link Omada ER605 v2.30, firmware 2.4.5 | Received, adopted, updated |
| Main switch | TP-Link Omada SG2016P (16-port, 8×PoE+, 120W budget) | Received, adopted, wired in; powers the office AP via PoE (make sure the AP is in an actual PoE port — only 8 of the 16 are) |
| Access point #1 | TP-Link Omada EAP650 | Received — mounting in the office first, powered via its own DC adapter until the switch's PoE+ is available |
| Access point #2 | TP-Link Omada EAP650 (same model as AP #1) | Installed and configured (living room) — chosen over the EAP610 (AX1800, no 160 MHz on 5 GHz) so both APs are identical; the peak-speed difference is irrelevant to the actual couch problem, which is signal quality. Living-room/dining-area coverage, mounted above the TV (see Wi-Fi section) |
| Living-room switch | TP-Link Omada ES205GP (5-port, 4× PoE+ 802.3at/af, 65W budget) | Installed and configured — note the P: the plain ES205G in earlier notes has no PoE. Easy Managed tier, but supports 802.1Q VLANs (up to 32 groups) via Omada Controller, adopted like the other devices. 3 devices need ports (AP, TV, streaming Pi), so 5 ports is plenty — no need for an 8-port unit |
Homeserver
- Dell OptiPlex 3000 (Core i3-12300T, 12th gen, 16GB DDR4, 512GB NVMe),
192.168.30.20on Servers — the actual homeserver, set up 2026-10-04. Full setup log, hardware checks and the NVMepcie_aspm=offworkaround: homeserver.md. (Earlier plans: a new Beelink EQ14, then a used Intel NUC from Willhaben, 8th-gen i3/16GB/128GB, ~€155.) - OS: Ubuntu Server 26.04 LTS + Docker Compose, headless, SSH keys only, no disk encryption (boots unattended after power cuts). No Proxmox/hypervisor.
- Home Assistant via the official "Home Assistant Container" image (not Home Assistant OS) — matches running everything else as plain Docker.
- Config management: Ansible, run from David's own machine over SSH (no footprint on the server itself).
- Kubernetes explicitly rejected for home services (no benefit on a single node). Will build a separate k3s learning cluster later on already-owned Raspberry Pis (RPi4 and older), kept fully separate from production services — motivated by wanting K8s reps for work, not by home-service needs.
Living room
- Single existing Ethernet cable feeds this area from the wall. Plan: run that connection to a spot above the TV, and put the new ES205GP switch + second AP (EAP650) there, so the TV and streaming Pi are each only a short patch cable away. (Alternative considered and rejected: switch + AP at the wall outlet above the cabinet, which would need two ~5 m runs to the TV and Pi instead of one longer run.)
- Connected there: the second AP (EAP650, PoE-powered from the ES205GP — no separate adapter), the TV (wired, on IoT), and the Raspberry Pi for game streaming (on Trusted).
- VLAN plumbing this needs: the ES205GP uplink port and the AP's port are trunks carrying Trusted (10) / IoT (20) / Guest (40) tagged; TV port = access port on IoT; Pi port = access port on Trusted. The SG2016P port feeding this cable must be a matching trunk (remember the lesson from the first AP: every VLAN needs to be tagged on every hop between the AP and the ER605, or clients associate but never get an IP).
- Streaming Steam games to the TV: try the already-owned RPi4 with Moonlight first (well-proven, hardware-decode, zero cost) before buying anything. Fallback if insufficient: new RPi5 (~€150) or a cheap N100 mini PC (similar price, more flexible, slightly higher latency/idle power).
- Streaming Pi should sit on the Trusted VLAN (same as the gaming PC) to avoid an unnecessary routing hop.
Full wired device list (needs a switch port)
Linux PC · Windows gaming PC · partner's PC · printer (optional) · Synology NAS · homeserver (OptiPlex) · OctoPrint Pi · AP (via living-room switch) · streaming Pi (via living-room switch)
Network architecture
VLAN plan
| VLAN | Subnet | Purpose |
|---|---|---|
| 1 — Default | 192.168.0.0/24 |
Empty since 2026-10-04 — kept only as the recovery/adoption network for factory-reset devices |
| 10 — Trusted | 192.168.10.0/24 |
Personal devices, PCs (David's PC fixed at .10), streaming Pi (avoids an extra routing hop for game streaming) |
| 20 — IoT / Home Automation | 192.168.20.0/24 |
OctoPrint + webcam, sensors, light bulbs, camera, robot vacuum, TV, printer — internet allowed (needed for TV streaming apps + vacuum's cloud control), LAN access denied by ACL |
| 30 — Servers / Homelab | 192.168.30.0/24 |
NAS (.10), homeserver OptiPlex (.20) |
| 40 — Guest | 192.168.40.0/24 |
Isolated (Omada "Isolate Network" flag), internet-only |
| 99 — Management | 192.168.99.0/24 |
Switches and APs (in use since 2026-10-04) |
Infrastructure addresses:
| Device | Model | Address | Fallback IP |
|---|---|---|---|
| Office – VPN Router | ER605 | Gateway in every VLAN (.1) |
– |
| Office – 16 Port Switch | SG2016P | 192.168.99.10 (static) |
– |
| Living Room – 5 Port Switch | ES205GP | 192.168.99.11 |
192.168.99.211 |
| Office – WiFi AP | EAP650 | 192.168.99.20 |
192.168.99.220 |
| Living Room – WiFi AP | EAP650 | 192.168.99.21 |
192.168.99.221 |
-
Window/door/temperature sensors are Zigbee via a USB coordinator on the homeserver, not IP devices — they never touch VLAN 20's network; Home Assistant talks to them over the local Zigbee radio directly.
-
Default-deny between VLANs is not automatic on Omada — inter-VLAN routing is allow-all by default; ACL rules must be built manually (e.g., Home Assistant → IoT devices).
-
ACL direction for alerts/control is Servers → IoT (Home Assistant reaching in to poll/control devices), not the reverse — IoT devices never need to initiate connections out to notify anyone.
-
TV casting only needs Trusted → IoT allowed (the casting source connects out to the TV); return traffic flows back automatically as part of that established connection, no reverse rule needed. Discovery is handled by the ER605's mDNS repeater.
-
ACL rules built (Omada ACL types:
Network= exact match,!Network= any network except the one picked; DirectionLAN-LANvsLAN-WANvsWAN-INare separate scopes — aLAN-LANrule has zero effect on internet access): Gateway ACLs as of 2026-10-05 (LAN→LAN, evaluated top to bottom):# Name Policy Source Destination 1 Printer to NAS SMB Permit (TCP) IP group PrinterIP-Port group NAS SMB(192.168.30.10:445) — scan-to-network for Paperless, see../docker/paperless/2 IoT Outwards Deny IoT !IoT(everything except IoT)3 Guest Outwards Deny Guest !Guest(everything except Guest)4 Server Outwards Deny Servers Management, Guest 5 Trusted Outwards Deny Trusted Guest 6 Controller - Management Permit, disabled IP group Omada ControllerManagement - Internet access is untouched by all of these, since WAN isn't in scope for a
LAN-LANrule. - Everything else (Trusted↔Servers, Trusted→Management, Servers→IoT, Trusted→IoT) relies on Omada's allow-all-by-default behavior.
- The ACLs are stateful: replies to allowed connections pass, so the controller on Servers reaches VLAN 99 devices without an extra rule even though Server Outwards denies Servers → Management (the devices open the connection to the controller).
- Printer discovery from Trusted uses an Omada Bonjour (mDNS) rule, IoT → Trusted.
- Planned tightening (Server Outwards also covering Trusted/Default, DNS exceptions, locking down Default/Management): see todo.md.
- Internet access is untouched by all of these, since WAN isn't in scope for a
-
WAN-IN rules generally aren't needed — NAT already blocks all unsolicited inbound traffic by default; WAN-IN only matters for scoping something you've already port-forwarded (e.g. the VPN port).
-
ER605 supports full per-port 802.1Q tagging/untagging/PVID; no practical VLAN-count limit for this setup.
-
ER605's built-in mDNS repeater bridges Bonjour/mDNS discovery across VLANs (relevant for reaching OctoPrint/HA by local hostname).
-
ER605's LAN DNS feature (firmware 2.3.0+) allows manual local hostname → IP entries — but like all DNS, it cannot encode a port number. Non-standard-port services (OctoPrint:5000, HA:8123, Omada Controller:8043, Spoolman:7912, Portainer:9000, etc.) still need a reverse proxy for clean no-port URLs.
Wi-Fi
- Router is headless by design (lives in a cupboard — its own Wi-Fi radio would be useless there anyway).
- First AP (EAP650) is in the office. Measured signal (interim position, AP on top of a closet — not yet at its final ceiling mount): office desk -42 dBm, office at the 3D printer -39, master bedroom -42, kitchen -57, storage room (door closed) -59, living-room couch -70 (matches a measured drop from ~50 to 10-20 Mbit there). Coverage is good everywhere except the couch nook, which sits behind the bathroom and hallway walls relative to the office. Rough thresholds: better than -60 good, to about -67 reliable for streaming/calls, -70 marginal, worse than -75 weak.
- Decision: add a second AP (EAP650) in the living/dining area, mounted above the TV — a single weak spot alone wouldn't have justified it (phone use at -70 is fine, and the TV/streaming Pi are wired), but David wants to keep working from the couch or dining table on a laptop, where -70 dBm is genuinely marginal. Wired backhaul, so no mesh needed.
- A ping to an idle phone is not a valid coverage test — phones in Wi-Fi power-save routinely show 100-500 ms round trips with a strong signal. Use the AP's own reading (Controller → Clients → the device's signal/link rate), a screen-on ping, or a throughput test instead.
- Worth re-measuring the couch once the office AP is at its real ceiling position and again after the second AP is up, for a before/after comparison.
VPN
- WireGuard runs on the ER605 itself, not on the homeserver — avoids extra port-forwarding + static routing that a homeserver-hosted VPN would need. Working as of firmware 2.4.5.
- ER605 firmware must be at least 2.4.5 for WireGuard VPN Server to appear as an option in the Controller at all — on the pre-update firmware (2.3.3), WireGuard wasn't listed, and the OpenVPN server that was available silently never actually started (config looked correct in the Controller — enabled, user linked, no errors in Audit Logs — but the daemon never bound to its port, confirmed via
ECONNREFUSEDon local, WAN-direct, and external tests). Updating firmware fixed both. - Local Networks scoped to Servers (30) + IoT (20) — remote access to the NAS/self-hosted services and things like OctoPrint, not to personal devices on Trusted. (Was briefly set to Trusted-only, then discovered to actually have every network selected — same "field silently left on all networks" class of bug hit earlier with OpenVPN's Local Networks. Corrected to the minimal actual-need scope: Servers + IoT, explicitly excluding Management for now — no current need for it, easy to widen later.) Tunnel Mode Split (only the selected networks' traffic goes through the tunnel, not general browsing).
- VPN client IP pool:
192.168.66.0/24— deliberately outside all VLAN subnets, no fixed convention requirement (doesn't have to be a10.xrange). - Needs its own port-forward rule (Settings → Transmission → NAT → Port Forwarding) separate from any VLAN/ACL config: WAN1, external+internal port
51820, internal IP192.168.0.1(the gateway's own Default-network address, since the VPN terminates on the gateway itself), protocol UDP or All — not TCP only (a real bug hit during OpenVPN testing: the port-forward was accidentally set to TCP-only while OpenVPN used UDP, causing a silent timeout that looked identical to "nothing is running" until diagnosed via matching local vs. externalECONNREFUSEDsignals). - No additional WAN-IN ACL rule was needed on top of the port-forward — confirmed via the external test returning an active
ECONNREFUSEDrather than a silent timeout, which proves traffic was already reaching the gateway. - Android: WireGuard/OpenVPN aren't part of Android's built-in VPN framework (that only covers IKEv2/IPsec and L2TP natively) — use the official WireGuard app (supports QR-code import — zoom the browser in if the phone camera won't scan it off a monitor) or OpenVPN Connect app.
- DynDNS instead of paying LIWEST for a static IP — real annual cost difference (~€200+/year for static IP vs. free DynDNS), and cable IPs don't change often in practice anyway. Decided against DuckDNS — David already owns a domain via INWX, which has its own DynDNS2-compatible service, so used that instead (no shared
duckdns.orgdomain, and INWX's DomRobot API has a ready-madeacme.shplugin for future Let's Encrypt DNS-01 certs on NPM).- Set up an INWX DynDNS account (their control panel's dedicated DynDNS section, not general domain/DNS management) — this single step both creates the DNS record for the chosen hostname and generates a separate DynDNS-scoped username/password (not the main INWX account login — narrower blast radius if it ever leaked).
- Configured on the ER605 via Device Config → Gateway → DNS → Dynamic DNS, Service Provider Custom:
- Update-URL:
https://[USERNAME]:[PASSWORD]@dyndns.inwx.com/nic/update?hostname=[DOMAIN]&myip=[IP](Omada's Custom DDNS placeholders — substituted from the Username/Password/Domain Name fields, not typed literally into the URL) - The actual filled-in URL/credentials are not written anywhere in this repo — keep them out of anything committed.
- Update-URL:
- Working — verified via
dig +short <hostname>returning the ER605's current public IP. - WireGuard client
Endpointdoesn't auto-update to a hostname from the Controller UI (it always embeds the raw WAN IP in exported configs) — WireGuard's config format supports hostnames inEndpointnatively though, so just manually edit the line (in the downloaded.confor directly in the WireGuard app's peer settings) toEndpoint = <hostname>:51820after generating a client config.
- General WireGuard gotcha, same shape as the Endpoint one above: fields set on the server config (e.g. Primary DNS Server) do not retroactively apply to peers whose config was already generated/imported before the change — WireGuard bakes settings into the client's config at generation time, it isn't pushed live the way DHCP options are. After changing a server-side field, either regenerate and re-import the client config, or edit the existing peer directly in the WireGuard app (same trick as the Endpoint fix).
- Bridge mode confirmed active on the modem — ER605 WAN gets the public IP directly (see TODO above).
Local DNS & naming
- Naming scheme settled on:
<name>.home.staffenberger.at— a subdomain of David's own already-owned INWX domain, not.local(reserved for mDNS/Bonjour, RFC 6762 — using it for manual DNS records risks conflicting with automatic mDNS resolution) and not.homeor.home.arpa(the latter is the IETF-correct reserved suffix per RFC 8375, but rejected as too unfriendly for the partner to read/type). These records exist only in Pi-hole's local DNS — never published to INWX's real public DNS, so nothing is internet-exposed by using a real owned domain for the naming. - Pi-hole now runs on the OptiPlex (
192.168.30.20, settings imported from the NAS instance via Teleporter). Every service name is an individual Local DNS Record pointing at192.168.30.20(NPM), which forwards to the real address and port — including services on other devices such as OctoPrint. Current names:omada,pihole,ha,octoprint, plusnas(moved over from the NAS Pi-hole) (.home.staffenberger.at). DHCP still hands out the NAS Pi-hole (192.168.30.10) until the switch-over in todo.md. - Gotcha: a secondary/fallback DNS server on a VLAN's DHCP config causes intermittent resolution failures for internal-only names. Trusted's DHCP had Pi-hole as Primary DNS but
8.8.8.8(Google public DNS) as Secondary — client OS resolvers don't reliably always-prefer-primary (can race/round-robin), so any query that happened to hit8.8.8.8for an internal.home.staffenberger.atname failed immediately, since a public resolver has no knowledge of it. Symptom looked like "works for me, not for my partner" / inconsistent across devices. Fix: don't set a secondary DNS pointing outside Pi-hole at all — Pi-hole already forwards normal internet lookups upstream itself. - Same stale-DHCP-lease pattern hit all week applies to DNS server changes too — a device won't pick up a newly-configured DNS server until it renews its lease (Wi-Fi toggle,
ipconfig /release+/renew, etc.), same as VLAN reassignment.
Omada Controller
- Self-hosted Omada Software Controller (Docker) instead of TP-Link's cloud controller — avoids a vendor cloud relay, in line with the general "no cloud relay" networking principle.
- Ran temporarily on David's desktop, migrated to the OptiPlex on 2026-10-04 (backup → restore in the setup wizard → built-in device migration; all five devices reconnected without rebooting). Image
mbentley/omada-controller:6.3(6.3.0.45) — never thelatesttag, which still points at v5. See omada-controller-migration.md and../docker/omada/. - Watch for controller version mismatches between export and import — TP-Link/Omada requires matching major.minor(.patch) versions for restore; fallback is installing a specific matching version first, restoring, then upgrading.
Reverse proxy
- Chosen: Nginx Proxy Manager (NPM) — single GUI, single source of truth for all proxy configs, works uniformly whether the target is a Docker container on the homeserver or a bare-metal service elsewhere (e.g. OctoPrint on the Pi). Runs on the OptiPlex on clean 80/443/81; proxy hosts and lessons learned in
../docker/npm/. - TLS: Let's Encrypt wildcard for
*.home.staffenberger.atvia NPM's DNS challenge at INWX (decided 2026-10-04, replacing the earliermkcertlean). The names point at internal IPs, so only DNS validation works, and a wildcard needs it anyway. The credential is a dedicated INWX sub-user with minimal rights, so the "no full INWX account credentials in a script" concern is met; NPM still stores that password in plain text, so its data directory counts as a secret. Alternative kept in mind: acme-dns with a CNAME on_acme-challenge.home, limiting the credential to a single TXT record. - Traefik considered and rejected for home use (label-based config fights against wanting one central place to look); will get real Traefik exposure anyway via the k3s learning cluster, where it's the default ingress controller.
Switch port configuration (SG2016P)
- Access port = one VLAN, untagged — for every VLAN-unaware end device (PCs, NAS, printer, Pis, TV). Set the port's Native/Untagged network to the device's VLAN and leave Tagged empty; don't leave Default involved. Trunk = several VLANs tagged over one cable — only for infrastructure links (switch↔router, switch↔AP).
- Every VLAN must be tagged on every hop between an AP and the ER605, or clients associate to the SSID but never get an IP ("IP configuration failure"). Hit this twice: the first AP's port, then the switch's uplink to the ER605 (missing VLAN 10). The per-Network "Select Device Port" step and the per-port VLAN config are two views of the same thing; editing the port directly avoids the "cannot deselect the interface which selects the LAN as PVID" error.
- Management moved to VLAN 99 on 2026-10-04 (together with the controller move), Default is now empty and kept only as the recovery/adoption network:
- Uplink ports carry Default untagged (native) and all other VLANs tagged. VLAN 99 stays tagged, because the devices tag their own management traffic.
- APs: Config → IP Settings (network Management, fixed IP, fallback IP and gateway) plus the separate Management VLAN setting (Custom → Management). The IP Settings network alone does not change the VLAN.
- Switches: Config → Interface → VLAN 99 interface with Management VLAN enabled. The old VLAN 1 interface was disabled only after the new address answered.
- The ER605 stays as it is — it has an address in every VLAN.
- Extra safety net: Guest VLAN also enabled on the currently-used ports so anything unexpectedly plugged in lands isolated.
- After any port/VLAN or DHCP-scope change, a device keeps its old lease until it renews: toggle the port off/on in the Controller (equivalent to unplugging),
ipconfig /release+/renewon Windows, or Wi-Fi off/on on phones. - The
Networkcolumn in the Controller's Clients list is blank for wireless clients — cosmetic; the client's IP range is the real check of which VLAN it landed in. - Switch PoE is only on 8 of the 16 ports; a "dead" AP was just plugged into a non-PoE port (and then needed a minute to boot).
Backups
- Omada Controller: auto-backup enabled, daily for now (config is changing a lot; switch to weekly later). Local only on the OptiPlex for now, in
~/omada/data/autobackup(bind mount). Export a manual backup after every bigger change. Off-box copy is the next step — see the OptiPlex backup item in todo.md. - OptiPlex (
~/omada,~/pihole,~/npm,~/homeassistant): no off-box backup yet. Must be encrypted, because NPM's data contains the INWX sub-user password. Backups contain secrets (Device Account, WireGuard keys, DDNS settings) — never commit them. - Synology NAS → 6TB USB drive via Hyper Backup, deliberately manually connected (offline drive also guards against ransomware/accidental deletion), cadence every two weeks, recurring calendar reminder. Drive arrived as exFAT (DSM 7.3 mounts exFAT natively — the "exFAT Access" package no longer appears in Package Center — but exFAT has no journal, so an unclean unplug leaves a dirty flag and DSM reports "not ejected safely"); reformatted to ext4 via DSM (Control Panel → External Devices → Format — select the device row and Eject first if Format is greyed out). Hyper Backup has no plug-in trigger on DSM 7, so it's "plug in → Back up now → eject in DSM → unplug".
- Wizard order is destination first, then sources. Backup type Multiple versions, Folders and Packages (not LUNs).
- Sources: all shared folders (incl.
photo, Drive team folders,docker) +homes(~200 GB) + all applications (Synology Drive Server and Photos matter most — they carry the version history / albums / metadata that plain file copies lose), config backup on, client-side encryption on (password in Enpass), no schedule, Smart Recycle retention. homesis a reserved system share: its permissions can't be edited ("homes is reserved for the system"), and only Administrators-group accounts see it in Hyper Backup — neither is a problem.- Entire-system backup (restorable NAS image) isn't available to a local USB destination, only to a remote NAS / C2 — restoring means reinstalling DSM and packages and restoring data + config from the backup.
- Still to confirm after the first run finishes: a test restore of a personal Drive file and a personal photo (both users) to prove the application backup really covers personal data. Later: occasional off-site copy (3-2-1).
- Hyper Backup vs Hyper Backup Vault: Vault is only the receiving side on a second Synology (relevant for a future off-site copy), not needed for a local USB drive.
Cabling & power
- Cupboard patch cables: flat Cat6 is fine for short (2-3 m or less) data-only links — buy pure copper (CCA and very thin conductors are the risk), from a reputable maker (deleyCON flat U/UTP is AWG 27 stranded copper, unshielded, 1.5 mm thick, sold as 5-packs in white and individually in white/black, down to 25 cm; Goobay, InLine, Digitus/Delock are comparable). Unshielded is fine — twisted-pair geometry does the noise rejection. Flat cables are fragile where the cable meets the plug: no pull or sharp bend there. PoE runs (to the APs) and longer runs (e.g. to above the TV) should be round pure-copper cable, not flat. Verify each link shows 1000 Mbps in the Controller after swapping; a link that negotiates 100 Mbps or shows errors = swap the cable. (The TV port showed 100 Mbps earlier — probably the TV's own NIC, but unconfirmed.) Measure the real cable path with string and add 20-30 cm before choosing 2 m vs 3 m. Color-by-length coding isn't available in flat cables (only white/black) — use labels/Velcro, and a colored round multi-length set for loose spares.
- Socket strips (Austria: Schuko/Type F): a strip adds sockets, not capacity — plug two strips into different wall outlets, no daisy-chaining. Look for VDE/GS/ÖVE mark, 16 A, 3×1.5 mm² cable, surge protection for the PC/desk strip, and no switch (or a guarded one) for the router/switch/NAS strip. Mount with screws (keyhole slots/mounting plate), sockets facing sideways/down, never adhesive. The workshop-style metal strip David likes is bracket-mounted (Brennenstuhl Premium-Alu-Line is the closest wall-mountable match found; the AJ Produkte MOTION and Manutan ones are for their own workbench frames and only list CE, not VDE/GS).
Home automation plans
- Sensors: temperature/humidity, window-open monitoring, light bulb monitoring — via Zigbee-style sensors + a USB coordinator dongle (e.g. Sonoff Zigbee 3.0, ~€15–20) plugged into the homeserver.
- Camera to check on the cat: casual live viewing is computationally free. If smart detection (Frigate) is wanted later, add a Coral USB accelerator (~€70) rather than upgrading the CPU.
Services on the homeserver (OptiPlex)
Running (see homeserver.md and ../docker/):
- Omada Software Controller (migrated from the desktop 2026-10-04)
- Pi-hole (replacing the NAS instance)
- Nginx Proxy Manager
- Home Assistant (Container image)
Planned:
- Portainer — behind HTTPS, for viewing and restarts only; the compose files stay the source of truth
- Vaultwarden, with backups to the NAS
- Paperless-ngx — scanner drops into a NAS share, Paperless imports from there; data local on the OptiPlex, nightly
document_exporterto the NAS is the backup (DB on a network share rejected) - Filament spool manager
- Self-written Docker tools
- Everything set up by hand so far; bring it under Ansible (see todo.md)