# Concord NUC **Hostname**: concord-nuc / vish-concord-nuc **IP Address**: 192.168.68.100 (static, eno1) **Tailscale IP**: 100.72.55.21 **OS**: Ubuntu (cloud-init based) **SSH**: `ssh vish-concord-nuc` (via Tailscale — see `~/.ssh/config`) --- ## Network Configuration ### Static IP Setup `eno1` is configured with a **static IP** (`192.168.68.100/22`) via netplan. This is required because AdGuard Home binds its DNS listener to a specific IP, and DHCP lease changes would cause it to crash. **Netplan config**: `/etc/netplan/50-cloud-init.yaml` ```yaml network: ethernets: eno1: dhcp4: false addresses: - 192.168.68.100/22 routes: - to: default via: 192.168.68.1 nameservers: addresses: - 9.9.9.9 - 1.1.1.1 version: 2 wifis: wlp1s0: access-points: This_Wifi_Sucks: password: "REDACTED_PASSWORD" dhcp4: true ``` **Cloud-init is disabled** from managing network config: `/etc/cloud/cloud.cfg.d/99-disable-network-config.cfg` — prevents reboots from reverting to DHCP. > **Warning**: If you ever re-enable cloud-init networking or wipe this file, eno1 will revert to DHCP and AdGuard will start crash-looping on the next restart. See the Troubleshooting section below. --- ## Services | Service | Port | URL | |---------|------|-----| | AdGuard Home (Web UI) | 9080 | http://192.168.68.100:9080 | | AdGuard Home (DNS) | 53 | 192.168.68.100:53, 100.72.55.21:53 | | Home Assistant | - | see homeassistant.yaml | | Plex | - | see plex.yaml | | Syncthing | - | see syncthing.yaml | | Invidious | 3000 | https://in.vish.gg (public), http://192.168.68.100:3000 | | Materialious | 3001 | http://192.168.68.100:3001 | | YourSpotify | 4000, 15000 | see yourspotify.yaml | --- ## Deployed Stacks | Compose File | Service | Notes | |-------------|---------|-------| | `adguard.yaml` | AdGuard Home | DNS ad blocker, binds to 192.168.68.100 | | `homeassistant.yaml` | Home Assistant | Home automation | | `plex.yaml` | Plex | Media server | | `syncthing.yaml` | Syncthing | File sync | | `wireguard.yaml` | WireGuard / wg-easy | VPN | | `dyndns_updater.yaml` | DynDNS | Dynamic DNS | | `node-exporter.yaml` | Node Exporter | Prometheus metrics | | `piped.yaml` | Piped | YouTube alternative frontend | | `yourspotify.yaml` | YourSpotify | Spotify stats | | `invidious/invidious.yaml` | Invidious + Companion + DB + Materialious | YouTube frontend — https://in.vish.gg | --- ## Troubleshooting ### AdGuard crash-loops on startup **Symptom**: `docker ps` shows AdGuard as "Restarting" or "Up Less than a second" **Cause**: AdGuard binds DNS to a specific IP (`192.168.68.100`). If the host's IP changes (DHCP), or if AdGuard rewrites its config to the current DHCP address, it will fail to bind on next start. **Diagnose**: ```bash docker logs AdGuard --tail 20 # Look for: "bind: cannot assign requested address" # The log will show which IP it tried to use ``` **Fix**: ```bash # 1. Check what IP AdGuard thinks it should use sudo grep -A3 'bind_hosts' /home/vish/docker/adguard/config/AdGuardHome.yaml # 2. Check what IP eno1 actually has ip addr show eno1 | grep 'inet ' # 3. If they don't match, update the config sudo sed -i 's/- 192.168.68.XXX/- 192.168.68.100/' /home/vish/docker/adguard/config/AdGuardHome.yaml # 4. Restart AdGuard docker restart AdGuard ``` **If the host IP has reverted to DHCP** (e.g. after a reboot wiped the static config): ```bash # Re-apply static IP sudo netplan apply # Verify ip addr show eno1 | grep 'inet ' # Should show: inet 192.168.68.100/22 ``` --- ## Incident History ### 2026-02-22 — AdGuard crash-loop / IP mismatch - **Root cause**: Host had drifted from `192.168.68.100` to DHCP-assigned `192.168.68.87`. AdGuard briefly started, rewrote its config to `.87`, then the static IP was applied and `.87` was gone — causing a bind failure loop. - **Resolution**: 1. Disabled cloud-init network management 2. Set `eno1` to static `192.168.68.100/22` via netplan 3. Corrected `AdGuardHome.yaml` `bind_hosts` back to `.100` 4. Restarted AdGuard — stable --- ### 2026-02-27 — Invidious 502 / crash-loop - **Root cause 1**: PostgreSQL 14 defaults `pg_hba.conf` to `scram-sha-256` for host connections. Invidious's Crystal DB driver does not support scram-sha-256, causing a "password authentication failed" crash loop even with correct credentials. - **Fix**: Changed last line of `/var/lib/postgresql/data/pg_hba.conf` in the `invidious-db` container from `host all all all scram-sha-256` to `host all all 172.21.0.0/16 trust`, then ran `SELECT pg_reload_conf();`. - **Root cause 2**: Portainer had saved the literal string `REDACTED_SECRET_KEY` as the `SERVER_SECRET_KEY` env var for the companion container (Portainer's secret-redaction placeholder was baked in as the real value). The latest companion image validates the key strictly (exactly 16 alphanumeric chars), causing it to crash. - **Fix**: Updated the Portainer stack file via API (`PUT /api/stacks/584`), replacing all `REDACTED_*` placeholders with the real values. --- *Last updated: 2026-02-27*