542 lines
21 KiB
Markdown
542 lines
21 KiB
Markdown
# Bumblesloth Homelab — System Reference
|
||
|
||
> **Purpose:** This file is shared project knowledge for all homelab-related conversations. It describes the full infrastructure so that any discussion (game servers, cloud, networking, etc.) has the context it needs.
|
||
|
||
---
|
||
|
||
## Hardware
|
||
|
||
| Component | Detail |
|
||
|-----------|--------|
|
||
| Machine | HP ProDesk 600 G6 SFF |
|
||
| CPU | Intel i5-10500 (6 cores / 12 threads) |
|
||
| RAM | 16 GB DDR4 UDIMM (288-pin desktop, not SO-DIMM) |
|
||
| Storage | 512 GB NVMe SSD (single drive) |
|
||
| GPU | Integrated Intel UHD 630 (no dedicated GPU) |
|
||
| Expansion | 1× free PCIe x16 slot, 1× 3.5" bay |
|
||
| Form factor | Small Form Factor (SFF) — limits internal expansion |
|
||
|
||
---
|
||
|
||
## Operating System
|
||
|
||
- **OS:** Ubuntu Server 24.04 LTS (HWE kernel, minimized install, no snaps)
|
||
- **User:** `bumblesloth`
|
||
- **Hostname:** `slothhive`
|
||
- **IPv6:** Disabled system-wide (`/etc/sysctl.d/99-disable-ipv6.conf`) and in Docker (`daemon.json`)
|
||
---
|
||
|
||
## Network Configuration
|
||
|
||
### Local Network
|
||
| Setting | Value |
|
||
|---------|-------|
|
||
| IP | `192.168.178.30` (DHCP with static lease via FRITZ!Box MAC binding) |
|
||
| Subnet | `192.168.178.x` |
|
||
| Netplan config | `/etc/netplan/50-cloud-init.yaml` (dhcp4: no — eno1 enslaved to br0) + `/etc/netplan/99-bridge.yaml` |
|
||
| Network bridge | `br0` — bridges `eno1` for VM LAN access; inherits `eno1` MAC (`e8:d8:d1:d3:05:bd`) |
|
||
|
||
### Router
|
||
| Setting | Value |
|
||
|---------|-------|
|
||
| Current router | FRITZ!Box 5690 Pro (Deutsche Telekom fiber, SFP module) |
|
||
| DHCP DNS | AdGuard Home pushed via DHCP to all LAN devices (`192.168.178.30`) |
|
||
| DynDNS | Configured directly on FRITZ!Box — auto-updates ipv64.net on IP change |
|
||
|
||
### Public Access
|
||
| Setting | Value |
|
||
|---------|-------|
|
||
| Public IP | Dynamic (DynDNS managed) |
|
||
| DynDNS provider | ipv64.net |
|
||
| Base domain | `bumblesloth.ipv64.net` |
|
||
| A record | `bumblesloth.ipv64.net` → public IP (auto-updated by FRITZ!Box) |
|
||
|
||
### DNS — AdGuard Home
|
||
- **Wildcard rewrite:** `*.bumblesloth.ipv64.net → 192.168.178.30` (covers all subdomains on LAN)
|
||
- **Desktop DNS (CachyOS):** received automatically via FRITZ!Box DHCP — no manual override needed
|
||
- All devices on LAN receive AdGuard Home as DNS via FRITZ!Box DHCP
|
||
### DNS Records (CNAME → bumblesloth.ipv64.net)
|
||
| Subdomain | Service |
|
||
|-----------|---------|
|
||
| `cloud.bumblesloth.ipv64.net` | Nextcloud |
|
||
| `photos.bumblesloth.ipv64.net` | Immich |
|
||
| `actual-budget.bumblesloth.ipv64.net` | Actual Budget |
|
||
| `adguard.bumblesloth.ipv64.net` | AdGuard Home |
|
||
| `mealie.bumblesloth.ipv64.net` | Mealie |
|
||
| `git.bumblesloth.ipv64.net` | Gitea |
|
||
| `foundry.bumblesloth.ipv64.net` | Foundry VTT |
|
||
| `matrix.bumblesloth.ipv64.net` | Matrix/Synapse |
|
||
| `jellyfin.bumblesloth.ipv64.net` | Jellyfin |
|
||
| `paperless.bumblesloth.ipv64.net` | Paperless-NGX |
|
||
| `homeassistant.bumblesloth.ipv64.net` | Home Assistant |
|
||
|
||
### Firewall (UFW)
|
||
```
|
||
22/tcp — SSH
|
||
80/tcp — HTTP (Nginx Proxy Manager)
|
||
443/tcp — HTTPS (Nginx Proxy Manager)
|
||
222/tcp — Gitea SSH
|
||
53/tcp+udp — AdGuard Home DNS
|
||
2456:2458/udp — Valheim
|
||
15636/udp — Enshrouded (query)
|
||
15637/udp — Enshrouded (game)
|
||
ufw route allow in on br0 — VM bridge traffic (required for KVM VM LAN access)
|
||
ufw route allow out on br0 — VM bridge traffic (required for KVM VM LAN access)
|
||
```
|
||
|
||
### Router Port Forwarding
|
||
| Port(s) | Protocol | Target | Service |
|
||
|---------|----------|--------|---------|
|
||
| 80 | TCP | 192.168.178.30 | NPM (HTTP) |
|
||
| 443 | TCP | 192.168.178.30 | NPM (HTTPS) |
|
||
| 222 | TCP | 192.168.178.30 | Gitea SSH |
|
||
| 2456–2458 | UDP | 192.168.178.30 | Valheim |
|
||
| 15636 | UDP | 192.168.178.30 | Enshrouded (query) |
|
||
| 15637 | UDP | 192.168.178.30 | Enshrouded (game) |
|
||
|
||
### Remote Access
|
||
- **Tailscale** mesh VPN installed on slothhive, iPhone, and MacBook; MagicDNS enabled for hostname-based access
|
||
- **CachyOS desktop:** `/etc/hosts` entry `192.168.178.30 slothhive` for local SSH
|
||
---
|
||
|
||
## KVM Virtualisation
|
||
|
||
Home Assistant OS runs as a KVM virtual machine on slothhive, alongside Docker services.
|
||
|
||
### Installation
|
||
```bash
|
||
sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients virtinst bridge-utils ovmf
|
||
sudo usermod -aG libvirt bumblesloth
|
||
```
|
||
|
||
### Network Bridge
|
||
The VM needs a bridge interface to get its own LAN IP. Configured via `/etc/netplan/99-bridge.yaml`:
|
||
```yaml
|
||
network:
|
||
version: 2
|
||
ethernets:
|
||
eno1:
|
||
dhcp4: false
|
||
bridges:
|
||
br0:
|
||
interfaces: [eno1]
|
||
dhcp4: true
|
||
macaddress: e8:d8:d1:d3:05:bd
|
||
parameters:
|
||
stp: false
|
||
forward-delay: 0
|
||
```
|
||
`/etc/netplan/50-cloud-init.yaml` sets `eno1` to `dhcp4: false` to avoid conflict.
|
||
|
||
### Bridge Kernel Settings
|
||
```
|
||
/etc/sysctl.d/99-bridge.conf:
|
||
net.bridge.bridge-nf-call-iptables = 0
|
||
net.bridge.bridge-nf-call-ip6tables = 0
|
||
|
||
/etc/modules-load.d/br_netfilter.conf:
|
||
br_netfilter
|
||
|
||
/etc/sysctl.d/99-ipforward.conf:
|
||
net.ipv4.ip_forward = 1
|
||
```
|
||
|
||
### Common virsh Commands
|
||
```bash
|
||
virsh list --all # List all VMs and state
|
||
virsh start hass # Start HA VM
|
||
virsh shutdown hass # Graceful shutdown
|
||
virsh destroy hass # Force stop
|
||
virsh reboot hass # Reboot
|
||
virsh autostart hass # Enable autostart on boot
|
||
virsh dominfo hass # VM details
|
||
virsh domifaddr hass # VM IP address
|
||
virsh attach-device hass --file device.xml --persistent # Attach USB device
|
||
```
|
||
|
||
---
|
||
|
||
## Docker Infrastructure
|
||
|
||
### Installation
|
||
- Docker CE from official Docker repository (not distro packages)
|
||
- Docker Compose plugin (`docker compose`, not `docker-compose`)
|
||
- User `bumblesloth` in `docker` and `www-data` groups
|
||
### Networks
|
||
| Network | Type | Purpose |
|
||
|---------|------|---------|
|
||
| `proxy-net` | External, user-defined | Connects NPM to all web-facing services |
|
||
| `nc-internal` | Bridge (Nextcloud stack) | Isolates Nextcloud DB/Redis |
|
||
| `paperless-internal` | Bridge (Paperless stack) | Isolates Paperless DB |
|
||
| `matrix-internal` | Bridge (Matrix stack) | Isolates Synapse DB |
|
||
| `default` (per stack) | Auto-created | Internal communication within a compose stack |
|
||
|
||
> **Security model:** Services behind NPM on `proxy-net` don't need UFW rules or host port exposure — traffic flows 443/80 → NPM → container internally.
|
||
|
||
### Directory Structure
|
||
```
|
||
~/homelab/
|
||
├── nginx-proxy-manager/ # Reverse proxy + SSL
|
||
│ ├── docker-compose.yml
|
||
│ ├── data/
|
||
│ └── letsencrypt/
|
||
├── adguard-home/ # DNS resolver + ad blocking
|
||
│ └── docker-compose.yml
|
||
├── nextcloud/ # File sync & collaboration
|
||
│ ├── docker-compose.yml
|
||
│ ├── app-data/
|
||
│ ├── db-data/ # MariaDB data
|
||
│ └── user-data/
|
||
├── immich/ # Photo & video management
|
||
│ ├── docker-compose.yml
|
||
│ ├── .env
|
||
│ ├── library/
|
||
│ └── postgres/
|
||
├── paperless/ # Document management
|
||
│ ├── docker-compose.yml
|
||
│ └── db-data/ # PostgreSQL data
|
||
├── jellyfin/ # Media server
|
||
│ └── docker-compose.yml
|
||
├── mealie/ # Recipe manager
|
||
│ └── docker-compose.yml
|
||
├── gitea/ # Self-hosted Git
|
||
│ ├── docker-compose.yml
|
||
│ └── data/
|
||
├── actual-budget/ # Personal finance
|
||
│ ├── docker-compose.yml
|
||
│ └── data/
|
||
├── foundry/ # Foundry VTT
|
||
│ └── docker-compose.yml
|
||
├── matrix/ # Matrix/Synapse chat
|
||
│ └── docker-compose.yml
|
||
├── enshrouded/ # Enshrouded game server
|
||
│ ├── docker-compose.yml
|
||
│ └── enshrouded-data/
|
||
├── valheim/ # Valheim game server
|
||
│ ├── docker-compose.yml
|
||
│ ├── config/
|
||
│ │ ├── worlds_local/
|
||
│ │ ├── backups/
|
||
│ │ └── bepinex/
|
||
│ │ └── plugins/
|
||
│ └── data/
|
||
└── cups/ # AirPrint bridge for Epson ET-2810
|
||
└── docker-compose.yml
|
||
```
|
||
|
||
### Homelab Management Script
|
||
`/usr/local/bin/homelab` — supports `up`, `down`, `status`
|
||
|
||
**Design:** AdGuard Home and NPM are hardcoded as first/last. All other Docker services live in the `STACKS` array. The Home Assistant VM is managed separately via `virsh` commands within the same script.
|
||
|
||
**Startup order:** adguard-home → nginx-proxy-manager (3s delay) → HA VM → STACKS in order
|
||
**Shutdown order:** STACKS in reverse → HA VM → nginx-proxy-manager → adguard-home
|
||
|
||
### Auto-start on Boot
|
||
- **Docker services:** Systemd service at `/etc/systemd/system/homelab.service` — enabled, runs `homelab up` after Docker is ready on every boot.
|
||
- **HA VM:** `virsh autostart hass` — VM starts independently on boot via libvirt.
|
||
---
|
||
|
||
## Services
|
||
|
||
### Nginx Proxy Manager
|
||
| Setting | Value |
|
||
|---------|-------|
|
||
| Container | `jc21/nginx-proxy-manager:latest` |
|
||
| Ports | 80 (HTTP), 443 (HTTPS), 81 (admin, local only) |
|
||
| Network | `proxy-net` |
|
||
| Admin UI | `http://192.168.178.30:81` |
|
||
| Features | SSL via Let's Encrypt, Force SSL, HTTP/2, Block Common Exploits, WebSockets |
|
||
|
||
All web services are proxied through NPM. Game servers use direct UDP port forwarding, not NPM.
|
||
|
||
### AdGuard Home
|
||
| Setting | Value |
|
||
|---------|-------|
|
||
| Role | LAN DNS resolver, ad/tracker blocking |
|
||
| URL | `https://adguard.bumblesloth.ipv64.net` |
|
||
| Admin UI | `http://192.168.178.30:3000` |
|
||
| Port | 53 (bound to host) |
|
||
| Location | `~/homelab/adguard-home/` |
|
||
| Network | `proxy-net` |
|
||
| Wildcard rewrite | `*.bumblesloth.ipv64.net → 192.168.178.30` |
|
||
|
||
### Home Assistant
|
||
| Setting | Value |
|
||
|---------|-------|
|
||
| Role | Home automation, smart home integration |
|
||
| URL | `https://homeassistant.bumblesloth.ipv64.net` |
|
||
| Type | **KVM Virtual Machine** (not Docker) — runs Home Assistant OS 18.0 |
|
||
| VM name | `hass` |
|
||
| VM IP | `192.168.178.43` (DHCP via FRITZ!Box) |
|
||
| VM disk | `/var/lib/libvirt/images/haos.img` (64 GB) |
|
||
| VM RAM | 4096 MB |
|
||
| VM vCPUs | 2 |
|
||
| NPM forward | `192.168.178.43:8123` (by IP, not container name) |
|
||
| NPM features | WebSockets enabled, Force SSL |
|
||
| Autostart | `virsh autostart hass` |
|
||
|
||
**ZBT-2 USB Passthrough:**
|
||
| Setting | Value |
|
||
|---------|-------|
|
||
| Device | Nabu Casa ZBT-2 Thread/Matter border router |
|
||
| USB ID | `303a:831a` |
|
||
| Host path | `/dev/serial/by-id/usb-Nabu_Casa_ZBT-2_94A990D07314-if00` → `/dev/ttyACM0` |
|
||
| Passthrough method | `virsh attach-device hass ~/zbt2.xml --persistent` |
|
||
| Mode | Thread border router (OpenThread Border Router add-on in HA OS) |
|
||
|
||
**ZBT-2 passthrough XML (`~/zbt2.xml`):**
|
||
```xml
|
||
<hostdev mode='subsystem' type='usb' managed='yes'>
|
||
<source>
|
||
<vendor id='0x303a'/>
|
||
<product id='0x831a'/>
|
||
</source>
|
||
</hostdev>
|
||
```
|
||
|
||
**Integrations configured:**
|
||
- LG webOS TV (`192.168.178.22`) — added manually
|
||
- iPhone Companion app — connected via `https://homeassistant.bumblesloth.ipv64.net`
|
||
- ZBT-2 Thread border router — OpenThread Border Router add-on
|
||
**Notes:**
|
||
- HA OS runs as a KVM VM because the OpenThread Border Router add-on requires HA OS (not available in HA Container)
|
||
- VM uses `br0` bridge for LAN access — gets its own IP directly from FRITZ!Box DHCP
|
||
- NPM proxies to VM by IP (`192.168.178.43`) since the VM is not on `proxy-net`
|
||
- `trusted_proxies` config not needed in HA OS (handled differently than HA Container)
|
||
- mDNS auto-discovery doesn't work across Docker bridge — iOS Companion app must use manual URL
|
||
### Nextcloud
|
||
| Setting | Value |
|
||
|---------|-------|
|
||
| Role | Documents, file sync, collaboration |
|
||
| URL | `https://cloud.bumblesloth.ipv64.net` |
|
||
| Containers | `nextcloud-app` (Nextcloud), `nextcloud-db` (MariaDB), `nextcloud-redis` (Redis) |
|
||
| Networks | `proxy-net`, `nc-internal` |
|
||
| NPM forward | `nextcloud-app:80` |
|
||
| PHP memory | 1024M (`/usr/local/etc/php/conf.d/memory-limit.ini`) |
|
||
|
||
**Users:** root (admin, no data), kevin
|
||
|
||
**Cron:**
|
||
```
|
||
*/5 * * * * docker exec -u www-data nextcloud-app php -f /var/www/html/cron.php
|
||
```
|
||
Background jobs set to "Cron" in admin settings.
|
||
|
||
**Notes:**
|
||
- iOS/macOS CalDAV login can trigger brute-force protection; reset with `occ security:bruteforce:reset <ip>`
|
||
- `bumblesloth` user is in `www-data` group for host-level access to user-data directory
|
||
- Passwords in docker-compose.yml contain `$` special characters — escaped as `$$` to prevent Docker Compose variable interpolation warnings
|
||
### Immich
|
||
| Setting | Value |
|
||
|---------|-------|
|
||
| Role | Photo & video management, AI tagging, face recognition |
|
||
| URL | `https://photos.bumblesloth.ipv64.net` |
|
||
| Containers | `immich_server`, `immich_machine_learning`, `immich_redis`, `immich_postgres` |
|
||
| Networks | `proxy-net` + `default` (server), `default` only (others) |
|
||
| NPM forward | `immich_server:2283` |
|
||
|
||
**Users:** Kevin, mother
|
||
|
||
### Paperless-NGX
|
||
| Setting | Value |
|
||
|---------|-------|
|
||
| Role | Document management, OCR, tagging |
|
||
| URL | `https://paperless.bumblesloth.ipv64.net` |
|
||
| Containers | `paperless`, `paperless-db` (PostgreSQL), `paperless-redis`, `paperless-gotenberg`, `paperless-tika`, `paperless-gpt`, `ollama` |
|
||
| Networks | `proxy-net`, `paperless-internal` |
|
||
| NPM forward | `paperless:8000` |
|
||
|
||
**Backup:** PostgreSQL dump + document export → rsync to USB (`/mnt/backup-usb`, btrfs) nightly at 2 AM
|
||
**Manual sync to Proton Drive:** Fish function `paperless-backup` on CachyOS desktop (rclone automation pending upstream fix — PRs #9080/#9081)
|
||
|
||
**OCR workflow:**
|
||
- Automated metadata (title, tags, date) via paperless-gpt + `qwen2.5:7b`
|
||
- Manual OCR for difficult documents via Open WebUI + `llama3.2-vision:11b`; PDFs converted with `pdftoppm` (poppler)
|
||
- Claude (vision) as fallback for manual transcription
|
||
### Jellyfin
|
||
| Setting | Value |
|
||
|---------|-------|
|
||
| Role | Media streaming |
|
||
| URL | `https://jellyfin.bumblesloth.ipv64.net` |
|
||
| Network | `proxy-net` |
|
||
| NPM forward | `jellyfin:8096` |
|
||
| Hardware accel | Intel QSV via `/dev/dri` (Intel UHD 630) |
|
||
| Media path | `/srv/media/` (host mount) |
|
||
|
||
### Mealie
|
||
| Setting | Value |
|
||
|---------|-------|
|
||
| Role | Recipe manager |
|
||
| URL | `https://mealie.bumblesloth.ipv64.net` |
|
||
| Network | `proxy-net` |
|
||
| Backend | SQLite |
|
||
|
||
### Gitea
|
||
| Setting | Value |
|
||
|---------|-------|
|
||
| Role | Self-hosted Git |
|
||
| URL | `https://git.bumblesloth.ipv64.net` |
|
||
| Network | `proxy-net` |
|
||
| Backend | SQLite |
|
||
| SSH | Port 222 (UFW + FRITZ!Box port forwarding configured) |
|
||
| NPM forward | `gitea:3000` |
|
||
| Features | WebSockets enabled, Block Common Exploits enabled |
|
||
|
||
### Actual Budget
|
||
| Setting | Value |
|
||
|---------|-------|
|
||
| Role | Personal finance (replaced Firefly III) |
|
||
| URL | `https://actual-budget.bumblesloth.ipv64.net` |
|
||
| Network | `proxy-net` |
|
||
| NPM forward | `actual-budget:5006` |
|
||
|
||
### Foundry VTT
|
||
| Setting | Value |
|
||
|---------|-------|
|
||
| Role | TTRPG virtual tabletop |
|
||
| URL | `https://foundry.bumblesloth.ipv64.net` |
|
||
| Network | `proxy-net` |
|
||
| NPM | WebSockets must be enabled in NPM proxy host |
|
||
|
||
### Matrix / Synapse
|
||
| Setting | Value |
|
||
|---------|-------|
|
||
| Role | Private self-hosted chat |
|
||
| URL | `https://matrix.bumblesloth.ipv64.net` |
|
||
| Server name | `matrix.bumblesloth.ipv64.net` (permanent — chosen to avoid .well-known delegation) |
|
||
| User IDs | `@kevin:matrix.bumblesloth.ipv64.net` |
|
||
| Containers | `synapse`, `matrix-db` (PostgreSQL), `coturn` |
|
||
| Networks | `proxy-net`, `matrix-internal` |
|
||
| NPM | WebSockets must be enabled |
|
||
| Federation | Disabled |
|
||
| Registration | Manual only |
|
||
|
||
### Enshrouded (Game Server)
|
||
| Setting | Value |
|
||
|---------|-------|
|
||
| Image | `mornedhels/enshrouded-server:latest` |
|
||
| Container | `enshrouded` |
|
||
| Ports | UDP 15636 (query), UDP 15637 (game) |
|
||
| Backups | Every 6 hours, max 4 kept |
|
||
| Max players | 8 |
|
||
| Update cron | Mondays at 4 AM |
|
||
|
||
**Force update:** `docker compose exec enshrouded supervisorctl start enshrouded-force-update`
|
||
**Note:** Server version may lag behind client after patches — Keen Games publishes dedicated server updates separately. Use force update command if version mismatch occurs.
|
||
|
||
### Valheim (Game Server)
|
||
| Setting | Value |
|
||
|---------|-------|
|
||
| Image | `ghcr.io/lloesche/valheim-server` |
|
||
| Container | `valheim` |
|
||
| Ports | UDP 2456–2458 |
|
||
| Mod framework | BepInEx (disabled — glibc incompatibility; vanilla only) |
|
||
| Auto-update | Only when idle |
|
||
| Backups | Every 6 hours, max 10 kept, max 7 days |
|
||
| Public | false (private server) |
|
||
| World | `BumbleWorld` (in `./config/worlds_local/`) |
|
||
|
||
**World switching:** Change `WORLD_NAME` in docker-compose.yml, run `docker compose down && docker compose up -d`.
|
||
**Adding mods:** Drop `.dll` files in `./config/bepinex/plugins/`, restart container.
|
||
|
||
### CUPS / AirPrint Bridge
|
||
| Setting | Value |
|
||
|---------|-------|
|
||
| Role | AirPrint bridge for Epson ET-2810 printer |
|
||
| Image | `drpsychick/airprint-bridge:latest` |
|
||
| Container | `cups` |
|
||
| Location | `~/homelab/cups/` |
|
||
|
||
---
|
||
|
||
## Common Commands
|
||
|
||
### Docker
|
||
```bash
|
||
docker ps # List running containers
|
||
docker compose up -d # Start stack (from its directory)
|
||
docker compose down # Stop stack
|
||
docker compose logs -f # Follow logs
|
||
docker compose restart # Restart stack
|
||
docker stats # Live resource usage
|
||
```
|
||
|
||
### Homelab Script
|
||
```bash
|
||
homelab up # Start all services in order
|
||
homelab down # Stop all services in reverse order
|
||
homelab status # Show status of all stacks + HA VM
|
||
```
|
||
|
||
### KVM / Home Assistant VM
|
||
```bash
|
||
virsh list --all # Show all VMs and state
|
||
virsh start hass # Start HA VM
|
||
virsh shutdown hass # Graceful shutdown
|
||
virsh reboot hass # Reboot VM
|
||
virsh domifaddr hass # Show VM IP address
|
||
virsh dominfo hass # Show VM details
|
||
virsh attach-device hass ~/zbt2.xml --persistent # Attach ZBT-2 USB dongle
|
||
```
|
||
|
||
### Enshrouded
|
||
```bash
|
||
docker compose exec enshrouded supervisorctl start enshrouded-force-update # Force game update
|
||
docker compose exec enshrouded supervisorctl restart enshrouded-server # Restart server
|
||
```
|
||
|
||
### Nextcloud (OCC)
|
||
```bash
|
||
docker exec -u www-data nextcloud-app php occ [command]
|
||
# Useful commands:
|
||
# user:list, user:add
|
||
# files:scan --all / files:scan <user>
|
||
# files:cleanup
|
||
# maintenance:mode --on / --off
|
||
# maintenance:repair
|
||
# trashbin:cleanup --all-users
|
||
# app:list, app:enable <app>, app:disable <app>
|
||
# security:bruteforce:reset <ip>
|
||
```
|
||
|
||
### System
|
||
```bash
|
||
df -h / # Disk usage
|
||
htop # System resources
|
||
sudo ufw status # Firewall rules
|
||
crontab -l # Scheduled tasks
|
||
rsync -avh --progress # File transfers to slothhive over SSH
|
||
```
|
||
|
||
---
|
||
|
||
## Known Issues & Notes
|
||
|
||
1. **IPv6 disabled** — Docker Hub pulls fail over IPv6. Disabled system-wide in sysctl and in Docker daemon.json.
|
||
2. **BepInEx glibc error** — BepInEx doorstop requires GLIBC 2.33+; container has older version. Valheim runs vanilla.
|
||
3. **Nextcloud brute force** — iOS/macOS app login can trigger rate limiting. Reset with `occ security:bruteforce:reset <ip>`. Use app passwords if 2FA is enabled.
|
||
4. **Hairpin NAT** — Accessing public-facing services via domain from inside the LAN may not work on some routers. AdGuard wildcard rewrite handles this on the LAN.
|
||
5. **Single SSD** — All data on one 512 GB NVMe. Future plan: NAS for bulk storage, keep databases on SSD.
|
||
6. **Proton Drive rclone automation** — Blocked by upstream bug (PRs #9080/#9081 unmerged). Paperless backups synced manually via `paperless-backup` Fish function on CachyOS desktop.
|
||
7. **Matrix server name is permanent** — `matrix.bumblesloth.ipv64.net` used directly; changing it would require a full rebuild.
|
||
8. **WebSockets** — Must be explicitly enabled in NPM for Foundry VTT and Matrix/Synapse (and Home Assistant).
|
||
9. **DDR4 UDIMM (288-pin)** — HP ProDesk 600 G6 SFF requires standard desktop DIMMs, not SO-DIMM. Important for future RAM upgrades.
|
||
10. **DynDNS auto-update** — FRITZ!Box handles updates automatically, but after a power outage verify the public IP matches ipv64.net if services are unreachable externally.
|
||
11. **Nextcloud DB passwords** — Contain `$` special characters; escaped as `$$` in docker-compose.yml to avoid Docker Compose variable interpolation warnings.
|
||
12. **HA OS requires KVM VM** — The OpenThread Border Router add-on (required for ZBT-2 Thread mode) is only available in HA OS, not HA Container. KVM VM coexists with Docker on the same host without conflict.
|
||
13. **HA VM network** — VM gets its IP via DHCP from FRITZ!Box through the `br0` bridge. NPM proxies to the VM by IP (`192.168.178.43`), not container name. If the VM IP changes, update NPM proxy host.
|
||
14. **br0 bridge required for VM** — KVM VM LAN access requires `br0` network bridge. UFW must allow routed traffic on `br0` (`ufw route allow in/out on br0`). Bridge netfilter must be disabled (`bridge-nf-call-iptables = 0`) to avoid Docker iptables conflicts.
|
||
15. **HA VM disk size** — VM disk expanded to 64 GB (from default 32 GB) to accommodate HA Core Docker image download during initial setup.
|
||
16. **mDNS limitations** — Auto-discovery (for iOS Companion app, LG TV, etc.) does not work across Docker bridge or into the KVM VM from LAN devices. Use manual IP/URL for all HA integrations.
|
||
---
|
||
|
||
## Future Plans
|
||
|
||
- [ ] Proton Drive rclone automation once upstream PRs merge
|
||
- [ ] NAS integration (NFS mount for bulk media/backup storage)
|
||
- [ ] Resolve BepInEx GLIBC compatibility for Valheim modding
|
||
- [ ] Navidrome (music streaming)
|
||
- [ ] Confirm macOS CalDAV resolution (brute force reset + app password)
|
||
- [ ] Add IKEA Matter over Thread devices via ZBT-2 border router
|