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 mirrorvps-net/netbird/compose.yml+.env.example. - Not a Netbird peer — reachable only over the
wgr-vpsnettunnel through pi-home. - The only SSH account has no sudo; Docker is driven through a
docker:clicontainer (seerunbooks/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 |