18 KiB
N.O.M.A.D. Server
Offline survival/knowledge server and game server host.
Specs
- OS: Ubuntu 25.10 (bare metal)
- IP: 10.5.30.7
- CPU: Intel Core i7-4770K @ 3.50GHz (4c/8t)
- RAM: 32GB DDR3 1600MHz
- GPU: NVIDIA GeForce GTX 1080 (8GB VRAM)
- NIC: Intel I218-V (1GbE) + Aquantia AQC113 (10GbE)
- Motherboard: ASRock H97M Pro4
- UPS: None
Planned long-term role
- Keep NOMAD intentionally separate from PD's production stack.
- Continue to host Project NOMAD, game services, and the backup Technitium resolver.
- Accept only small bounded helper workloads; do not let it drift into being a second general-purpose production host.
Storage
| Device | Size | Mount | Purpose |
|---|---|---|---|
| Samsung SSD 840 (sdb) | 232.9GB | / (LVM 100GB) |
OS boot |
| WD Red HDD (sda) | 3.6TB | /mnt/hdd-1 |
Primary data |
| WD Red HDD (sdc) | 3.6TB | /mnt/hdd-2 |
Docker data-root |
| Seagate SSD (sdd) | 223.6GB | /mnt/ssd-1 |
Fast scratch |
Project N.O.M.A.D.
- Core compose project lives at
/opt/project-nomad→ symlinked from/mnt/hdd-1/project-nomad - Main compose file:
/mnt/hdd-1/project-nomad/compose.yml - Docker data-root:
/mnt/hdd-2/docker - Based on Crosstalk Solutions offline survival/knowledge server
- Current runtime is split between:
- the base
project-nomadcompose stack project-nomad-managedapp containers launched/managed by the N.O.M.A.D. admin layer- a few extra non-compose / non-NOMAD containers on the host
- the base
Docker Audit — 2026-05-14
Compose files found on NOMAD
/mnt/hdd-1/project-nomad/compose.yml(same project as/opt/project-nomad/compose.ymlvia symlink)/opt/newt/docker-compose.yaml
Running containers tied directly to compose files
project-nomad compose (/mnt/hdd-1/project-nomad/compose.yml)
nomad_adminnomad_mysqlnomad_redisnomad_dozzlenomad_disk_collectornomad_updater
newt compose (/opt/newt/docker-compose.yaml)
newt
Running containers managed by Project N.O.M.A.D. itself
These are labeled com.docker.compose.project=project-nomad-managed and io.project-nomad.managed=true, but no standalone compose files for them were found on disk during this audit.
nomad_cyberchefnomad_flatnotesnomad_kiwix_servernomad_kolibrinomad_ollamanomad_qdrant
Operator decision (John, 2026-05-14): this layer stays exactly as-is. It is self-maintained by Project N.O.M.A.D. Document it, but never manually touch, rebuild, migrate, or “clean up” these containers unless John explicitly overrides that rule.
Known storage paths discovered from mounts / project storage:
- Flatnotes data:
/opt/project-nomad/storage/flatnotes - Kiwix ZIM library:
/opt/project-nomad/storage/zim - Kolibri data:
/opt/project-nomad/storage/kolibri - Ollama data/models:
/opt/project-nomad/storage/ollama - Qdrant storage:
/opt/project-nomad/storage/qdrant
Running containers not tied to discovered compose files
Likely host-managed / manually launched / app-managed elsewhere
whisper — fedirz/faster-whisper-server:latest-cpu
Operator decision (John, 2026-05-14): this can go away. Do not preserve it as a required service, but keep enough detail here to rebuild it if removing it causes issues.
- Purpose: ad-hoc Faster Whisper API endpoint
- Network mode:
bridge - Container IP during audit:
172.17.0.2 - Port publish: host
8786/tcp→ container8000/tcp(IPv4 and IPv6) - Restart policy:
unless-stopped - Entrypoint: image default
- Command:
uv run uvicorn --factory faster_whisper_server.main:create_app
- Environment:
WHISPER__MODEL=Systran/faster-distil-whisper-small.enWHISPER__INFERENCE_DEVICE=cpuUVICORN_HOST=0.0.0.0UVICORN_PORT=8000
- Mounts: none
- Compose labels: none found
- Rebuild-equivalent
docker run:docker run -d \ --name whisper \ --restart unless-stopped \ -p 8786:8000 \ -e WHISPER__MODEL=Systran/faster-distil-whisper-small.en \ -e WHISPER__INFERENCE_DEVICE=cpu \ -e UVICORN_HOST=0.0.0.0 \ -e UVICORN_PORT=8000 \ fedirz/faster-whisper-server:latest-cpu \ uv run uvicorn --factory faster_whisper_server.main:create_app
node-exporter — prom/node-exporter:v1.9.0
Operator decision (John, 2026-05-14): this can go away. Do not preserve it as a required service, but keep enough detail here to rebuild it if removing it causes issues.
- Purpose: host Prometheus metrics exporter
- Network mode:
host - Restart policy:
unless-stopped - Entrypoint:
/bin/node_exporter - Command:
--path.procfs=/host/proc--path.sysfs=/host/sys--path.rootfs=/rootfs--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)
- Read-only bind mounts:
/proc→/host/proc/sys→/host/sys/→/rootfs
- Compose labels: none found
- Rebuild-equivalent
docker run:docker run -d \ --name node-exporter \ --restart unless-stopped \ --network host \ -v /proc:/host/proc:ro \ -v /sys:/host/sys:ro \ -v /:/rootfs:ro \ prom/node-exporter:v1.9.0 \ --path.procfs=/host/proc \ --path.sysfs=/host/sys \ --path.rootfs=/rootfs \ '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
Pelican/Wings-managed game containers Operator decision (John, 2026-05-14): this is the game server stack. It stays. Document it; do not remove or migrate it unless John explicitly says so.
-
11d799cb-487a-416a-b6f9-9bf28f0e57e7- Image:
ghcr.io/pelican-eggs/yolks:java_25 - Network:
pelican_nw(172.20.0.2during audit) - Ports:
25565/tcpand25565/udpexposed on host0.0.0.0 - Restart policy:
no(Wings owns lifecycle) - Entrypoint:
/usr/bin/tini -g -- - Command:
/entrypoint.sh - Important env:
SERVER_IP=0.0.0.0SERVER_PORT=25565SERVER_JARFILE=server.jarSTARTUP=java --add-modules=jdk.incubator.vector -Xms128M -XX:MaxRAMPercentage=95.0 -Dterminal.jline=false -Dterminal.ansi=true -jar server.jarP_SERVER_UUID=11d799cb-487a-416a-b6f9-9bf28f0e57e7
- Mounts:
/var/lib/pelican/volumes/11d799cb-487a-416a-b6f9-9bf28f0e57e7→/home/container(rw)/etc/pelican/passwd→/etc/passwd(ro)/etc/pelican/group→/etc/group(ro)/etc/pelican/machine-id/11d799cb-487a-416a-b6f9-9bf28f0e57e7→/etc/machine-id(ro)
- Image:
-
d2aca31e-0d4d-433a-8295-cfad397dab0c- Image:
ghcr.io/pelican-eggs/yolks:java_21 - Network:
pelican_nw(172.20.0.3during audit) - Ports:
25566/tcpand25566/udpexposed on host0.0.0.0 - Restart policy:
no(Wings owns lifecycle) - Entrypoint:
/usr/bin/tini -g -- - Command:
/entrypoint.sh - Important env:
SERVER_IP=0.0.0.0SERVER_PORT=25566SERVER_MEMORY=8192MC_VERSION=1.21.1NEOFORGE_VERSION=21.1.229STARTUP=java -Xms128M -XX:MaxRAMPercentage=95.0 -Dterminal.jline=false -Dterminal.ansi=true @unix_args.txtP_SERVER_UUID=d2aca31e-0d4d-433a-8295-cfad397dab0c
- Mounts:
/var/lib/pelican/volumes/d2aca31e-0d4d-433a-8295-cfad397dab0c→/home/container(rw)/etc/pelican/passwd→/etc/passwd(ro)/etc/pelican/group→/etc/group(ro)/etc/pelican/machine-id/d2aca31e-0d4d-433a-8295-cfad397dab0c→/etc/machine-id(ro)
- Image:
These are expected to be managed by Wings/Pelican rather than a local compose file.
Dormant compose files found but not currently represented in running containers
- None found during this audit in searched paths.
- Search scope:
/opt,/srv,/home/fizzlepoof, and/mntfordocker-compose.yml,docker-compose.yaml,compose.yml, andcompose.yaml.
Decisions captured from this audit
- Project N.O.M.A.D.-managed app containers stay exactly as-is and are hands-off unless John explicitly says otherwise.
whisperandnode-exporterare not protected services; they can be removed, but their exact runtime has been documented above for rebuild/recovery.- Pelican/Wings-managed game containers are part of the permanent game-server stack on NOMAD and stay in place.
- Doris Dashboard source belongs in the homelab repo, and the live NOMAD runtime belongs at
/opt/doris-dashboard.
Doris Dashboard (local NOMAD homepage)
- Live runtime path:
/opt/doris-dashboard - Repo source path:
/home/fizzlepoof/repos/truenas-stacks/home/doris-dashboard - Purpose: local-only dashboard for briefing/news/weather/homelab pulse/Paperless review on NOMAD
- Generator:
home/doris-dashboard/bin/generate_dashboard.py - Interactive LAN server:
home/doris-dashboard/bin/dashboard_server.py - Service file source:
home/doris-dashboard/doris-dashboard.service - Runtime notes:
- Generated output and queue snapshots are runtime data; source/config lives in git, generated JSON/HTML does not need to be treated as canonical.
- Topic thumbs write back to
doris-digest/data/feedback.json. - Paperless acknowledge/dismiss state writes to
/opt/doris-dashboard/data/paperless_review_state.jsonon the live host.
Technitium Backup Resolver
- Live stack path:
/opt/technitium-nomad - Live secrets file:
/opt/technitium-nomad/.env - Resolver bind IP:
10.5.30.9 - Role: active DHCP-advertised backup Technitium resolver for the homelab
- Config is refreshed from PD's live Technitium directory by the PD-side sync runner every 15 minutes
- The live
.envis also backed up into the encrypted PD secrets repo asenv/technitium-nomad.env - Same-host checks from NOMAD to
10.5.30.9are unreliable because the resolver sits behind macvlan networking; verify from another LAN peer instead
LocalSend Trusted inbox
- Live stack path:
/opt/localsend-nomad - Repo source path:
/home/fizzlepoof/repos/truenas-stacks/localsend-nomad - Trusted bind IP:
10.5.1.16 - Advertised device name:
Doris Trusted Inbox - Role: headless LocalSend receiver for Trusted-LAN handoff into
/home/fizzlepoof/private/inbox-secrets - Runtime model: standalone Docker Compose stack on a Trusted-LAN macvlan (
enp5s0.51, VLAN 51) while the host stays on Servers (10.5.30.7) - LocalSend listener ports:
53317/tcp,53317/udp - Same-host checks from NOMAD to
10.5.1.16are unreliable because the receiver sits behind macvlan networking; verify from another Trusted-LAN peer instead - Inbox watcher for Minerva staging:
minerva-localsend-autosort.path - Sorter service:
minerva-localsend-autosort.service - Sorter script:
/home/fizzlepoof/.local/bin/minerva-localsend-autosort.py
MeshCore to MQTT relay
- Install date: 2026-05-18
- Install root:
/opt/mctomqtt - Config root:
/etc/mctomqtt - Service account:
mctomqtt:mctomqtt - Installer metadata:
.version_inforeportsinstaller_version: 1.3.0.0-preview, repoCisien/meshcoretomqtt, branchmain, commit10f7c0e - Detected install type marker:
/opt/mctomqtt/.install_typecontainsdocker - Runtime model:
- Active runtime is a standalone Docker container named
mctomqtt - Image:
mctomqtt:latest - Command:
python3 /opt/mctomqtt/mctomqtt.py - User:
mctomqtt - Restart policy:
unless-stopped - Network mode:
bridge - Config bind mount:
/etc/mctomqtt:/etc/mctomqtt:ro - Device passthrough: the Heltec serial device is mapped directly into the container at the same
/dev/serial/by-id/...path
- Active runtime is a standalone Docker container named
- Systemd note:
- The packaged repo also includes
/opt/mctomqtt/mctomqtt.service, but it is not the active runtime on NOMAD - No installed unit was present in
/etc/systemd/systemor/lib/systemd/system - The bundled unit expects
/opt/mctomqtt/venv/bin/python3, but novenv/directory exists under/opt/mctomqtt - Treat the systemd unit as an unused package artifact for this host unless the deployment model changes later
- The packaged repo also includes
- Config layering:
- Base reference:
/etc/mctomqtt/config.toml - Preset overlay:
/etc/mctomqtt/config.d/10-meshmapper.toml - Local overrides:
/etc/mctomqtt/config.d/99-user.toml
- Base reference:
- Current local overrides observed:
- IATA region code set to
BNA - Serial device pinned to
/dev/serial/by-id/usb-Espressif_Systems_heltec_wifi_lora_32_v4__16_MB_FLASH__2_MB_PSRAM__441BF670B684-if00 - Enabled broker targets include MeshMapper, LetsMesh US, and NashMe
- Credentials/secrets are stored inline in
99-user.toml; do not mirror them into git-backed docs
- IATA region code set to
- Container health observed during inspection:
- Logs show the relay loading all three config layers, opening the Heltec serial device, and connecting successfully to MeshMapper, NashMe, and LetsMesh US after restart
- The current container had been up about 5 minutes during inspection with
MQTT: 3/3, zero failures, and live RX air-time reported - An earlier start logged one DNS resolution failure for a broker label shown as
custom-2, but the current running container recovered and all three named brokers connected cleanly
- Container logs / inspection:
- Use
docker logs mctomqttfor runtime output - Use
docker inspect mctomqttfor bind mounts, device mappings, and restart policy
- Use
- Documentation linkage:
- Related mesh stack notes live in MESHTASTIC.md
Live deployment path rule
- On NOMAD, live service roots belong under
/opt/<service>. - That includes host-run services and standalone Docker Compose deployments that are not part of the core Project N.O.M.A.D. stack.
- Keep service-local runtime data with the service under
/opt/<service>/dataunless there is a clear reason to place heavy state elsewhere. - Examples:
/opt/newt,/opt/doris-dashboard,/opt/pihole-nomad. - Do not run production services from any agent workspace or ad-hoc checkout under
/home/fizzlepoof/.openclaw/workspace.
Safe to remove / how to restore
Safe to remove now
whispernode-exporter
Removing them should not be treated as a Project N.O.M.A.D. change or a Wings/Pelican change. They are standalone host-level containers from this audit’s point of view.
Restore checklist if removal causes trouble
- Confirm what broke:
- speech/transcription endpoint dependency → restore
whisper - Prometheus scraping / host metrics gap → restore
node-exporter
- speech/transcription endpoint dependency → restore
- Recreate the container using the documented
docker runcommand in this file. - Verify it came back cleanly:
docker ps --filter name=whisperdocker ps --filter name=node-exporterdocker logs --tail 50 whisperdocker logs --tail 50 node-exporter
- Re-check any dependent dashboards, scrapers, or automations.
- If the recreated container needs to persist long-term again, document why before leaving it in place.
Restore intent
- Restore
whisperonly if something still expects a local Faster Whisper HTTP endpoint on port8786. - Restore
node-exporteronly if something still depends on host Prometheus metrics from this box. - Do not fold either one into Project N.O.M.A.D. or Wings/Pelican casually; if they come back, they come back as deliberate standalone services unless John says otherwise.
Pelican Panel (Game Server Management)
- URL:
https://panel.paccoco.com - Stack: PHP 8.4 + nginx + MariaDB (native, not Docker)
- Panel files:
/var/www/pelican - DB: MariaDB, database
pelican, userpelican@127.0.0.1 - APP_URL:
https://panel.paccoco.com - TRUSTED_PROXIES:
* - Cron:
* * * * * php /var/www/pelican/artisan schedule:run(www-data) - Admin user:
fizzlepoof - Reverse proxy: Pangolin via Newt container at
/opt/newt
Wings (Game Server Daemon)
- Binary:
/usr/local/bin/wings - Config:
/etc/pelican/config.yml - Systemd:
wings.service - ExecStart:
/usr/local/bin/wings --ignore-certificate-errors - API port: 8443
- SFTP port: 2022
- Node domain:
node1.paccoco.com(Pangolin, no auth, connection port 443) - Game server volumes:
/var/lib/pelican/volumes - Docker network:
pelican_nw(172.20.0.0/16)
Active Game Servers
- Container
11d799cb-487a-416a-b6f9-9bf28f0e57e7- Workload: Minecraft / Purpur-style Java server
- Java runtime image:
ghcr.io/pelican-eggs/yolks:java_25 - Public port:
25565TCP/UDP - Data path:
/var/lib/pelican/volumes/11d799cb-487a-416a-b6f9-9bf28f0e57e7
- Container
d2aca31e-0d4d-433a-8295-cfad397dab0c- Workload: modded Minecraft-style server (NeoForge-related env present)
- Java runtime image:
ghcr.io/pelican-eggs/yolks:java_21 - Public port:
25566TCP/UDP - Data path:
/var/lib/pelican/volumes/d2aca31e-0d4d-433a-8295-cfad397dab0c
Networking Notes
panel.paccoco.com→127.0.0.1in/etc/hostsfor NAT loopback- nginx on 80 and 443 (self-signed cert) for local Wings → Panel
- Wings uses
--ignore-certificate-errorsfor self-signed cert - For local operator-safe Pelican health checks, use
http://10.5.30.7:8080instead of the self-signed TLS path; it redirects cleanly to/homewithout tripping certificate validation. - Pangolin resource
node1.paccoco.comhas auth disabled
Known Quirks
- NVIDIA container toolkit repo has invalid GPG key — remove
/etc/apt/sources.list.d/*nvidia*if apt errors - Port 8080 occupied by
nomad_admincontainer — Wings uses 8443 - Interactive artisan commands break over SSH — always use inline flags
- Wings CORS derived from
remote:URL — keep remote ashttps://and use--ignore-certificate-errors
Newt Tunnel
- Container:
newtat/opt/newt/docker-compose.yaml network_mode: host- Connects to Pangolin VPS at
https://paccoco.com
Pending
- Regenerate Wings token (was exposed in chat)
- Regenerate Newt secret (was exposed in chat)