Skip to content

Nodes

All nodes run Debian-family. This page records verified live state: running units, timers, exports and containers.

Runtime pattern: pi-home is native systemd (no Docker). vps-apps and vps-net run Docker Compose, one project per application directory. The repository is cloned at /opt/homelab on vps-apps and vps-net only. No node auto-syncs: the homelab-sync timer on vps-apps is disabled, so nothing commits or pushes on its own and every node's repo is edited deliberately. vps-net's live compose is /root/docker-compose.yml, mirrored by vps-net/netbird/compose.yml.

node hardware runtime
pi-home single-board · 1 GB RAM · 687 GB HDD + SD root native systemd
vps-apps VPS · 8 GB RAM · 4 vCPU · 75 GB disk Docker Compose
vps-net VPS · 1 GB RAM · 2 vCPU Docker Compose (minimal)

pi-home — running units

unit bind role
pihole-FTL all interfaces :53 (DNS + DHCP) · web/API :8089, :8489 fleet DNS resolver
cloudflared loopback control port only public tunnel (token-managed)
vaultwarden mesh :8001 password vault
radicale mesh :5232 CalDAV/CardDAV
ntfy mesh :9999 push notifications
pocket-id mesh :1411 OIDC provider
syncthing mesh :8384 · peer sync :22000 file sync
filebrowser all interfaces :8090 HDD file manager
hydroxide mesh :1025 SMTP · :1143 IMAP mail bridge
beszel-hub :8125 metrics hub
beszel-agent :45876 metrics agent → hub
beszel-agent-native — duplicate agent to the local hub (one should be retired)
nfs-server (+ rpcbind/mountd/statd) :2049, :111, RPC ports exports /mnt/pi-hdd/backups, only to the vps-apps tunnel IP
smbd/nmbd LAN :445, :139 default shares only (no music export)
dropbear 0.0.0.0:27925 SSH
mesh-services-watchdog — (timer) restarts mesh-bound units that lose their listener
fail2ban · ufw · netbird · dietpi-dashboard :5252 · telegram-bot · php8.4-fpm — platform / hygiene

Recurring timers: restic-backup@data 00:00 UTC · restic-backup@config 00:30 UTC · cf-ddns 5 min · beszel-agent-update · phpsessionclean · mesh-services-watchdog 5 min.

Storage: SD root; 687 GB HDD at /mnt/pi-hdd (restic repos + WebDAV drop); application state under the dietpi userdata root.

vps-apps — running containers

Published ports bind the node's mesh IP unless flagged. Data root: /opt/homelab-data/<app>/.

stack containers port
romm romm · romm-db (MariaDB) :8333
dawarich app · sidekiq · db (PostGIS) · redis · watchdog :3000
musicload musicload :8000
backrest backrest :9898
docs mkdocs-material :8001
linkding linkding :9090
2fauth 2fauth :8700
actual actual-server :5006
actual-mcp actual-mcp loopback :3010 (hermes only)
beets / calibre-web / shelfmark / bentopdf as named :8337 / :8046 / :8084 / :8095
uptime-kuma uptime-kuma :3001
homepage homepage · socket-proxy proxied, no published port
dockhand dockhand · socket-proxy (scanners off) :3002
beszel-agent · hc-heartbeat as named —
hermes · hermes-dashboard agent runtime proxied, no published ports
joplin joplin · postgres :22300
sync-in sync-in · MariaDB :8080
dynacat dynacat · socket-proxy :7575
termix termix :8787
guacd guacd leftover, no consumer — stop candidate
oxicloud oxicloud · oxicloud-postgres :8086, :5432 (mesh 100.64.0.100) — tracked at /opt/docker/oxicloud/ + vps-apps/oxicloud/

Repos placement: tracked compose projects live in /opt/homelab/vps-apps/<app>/; joplin, sync-in, dynacat, termix, guacd and hermes live untracked under /opt/docker/ (oxicloud's tracked copy at vps-apps/oxicloud/ mirrors its deploy source /opt/docker/oxicloud/).

Tracked compose kept for reference with no container running: caddy, homeassistant, navidrome, metube, livesync-couchdb, musicgrabber, netbird-watchdog, opencloud.

Timers: docker-prune (weekly) · musicload-staging-purge (daily) · hermes-model-refresh (1 h) · hermes-session-prune (daily) · beszel-agent-update (daily). homelab-sync is present but disabled, so the repo is never synced automatically.

Docker daemon: logs capped (max-size 10m, max-file 3), MTU 1200, DNS = pi-home mesh IP + 9.9.9.9 (via daemon.json; the host uses systemd-resolved with the same targets).

vps-net — control plane, smallest possible footprint

container role
netbird-traefik TLS termination on 443
netbird-dashboard web UI
netbird-server management + signal + relay + STUN
netbird-proxy reverse proxy
  • Live compose /root/docker-compose.yml; tracked mirror vps-net/netbird/compose.yml + .env.example.
  • Not a Netbird peer — reachable only over the wgr-vpsnet tunnel through pi-home.
  • The only SSH account has no sudo; Docker is driven through a docker:cli container (see runbooks/netbird-down.md).
  • Images are digest-pinned; every version bump is deliberate (review release notes first).

Data roots

node config (tracked) data (backed up)
vps-apps /opt/homelab/vps-apps/<app>/ /opt/homelab-data/<app>/
vps-net /root/ (mirror: vps-net/netbird/) Docker volumes root_netbird_*
pi-home systemd units + /etc dietpi userdata tree