echo6-docs/vault/docs/services/services.md
Matt Johnson 44f0257376 docs: migrate Authentik (SSO keystone) to edge2 CT 105
- Authentik -> edge2 CT 105 (Postgres pg_dump/restore; SECRET_KEY carried verbatim; zero-downtime until ~2s cutover)
- Multi-block Caddy cutover: auth.echo6.co + notes.echo6.co outpost/forward_auth -> 100.64.0.36:9000
- runbook: add reboot tailscale-before-docker gotcha; clarify dnsmasq must NOT be repointed (points at Caddy host)
- source left stopped + intact on Contabo as cold rollback

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 05:49:07 +00:00

411 lines
29 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Current Services Inventory
## Active Services
| Service | Location | IP:Port | Access | Notes |
|---------|----------|---------|--------|-------|
| MeshMonitor | utility (CT 100) | 192.168.1.100:8080 | https://mesh.echo6.co | Meshtastic mesh monitoring (zvx-echo6/meshmonitor fork, multi-channel AutoAnnounce/AutoResponder) |
| Utility Caddy | utility (CT 101) | 192.168.1.101 / 100.64.0.8 | 199.6.36.163 (ports 80/443) | Reverse proxy for home services |
| Echo6 Search (SearXNG) | utility (CT 102) | 192.168.1.102:8080 | https://echo6.co | Branded search homepage (Docker, custom theme) |
| meshtasticd (AIDA-N2) | aida-nebra | 192.168.1.253:4403 | Internal | AIDA-N2(RPT,LLM) node !27780c47, Nebra 2W hat (ZebraHat), CLIENT_BASE role, fw 2.7.19. MeshAI (CT 108) connects via TCP localhost:4403 |
| Meshtastic CLI | mt-isr | 192.168.1.141 | Internal | Station G2 WiFi bridge + TCP management |
| meshtasticd | mt-burleybutte | 192.168.1.185:4403 | Internal | Software Meshtastic node (Nebra 2W hat) |
| IdahoMesh Headscale | utility (CT 106) | 192.168.1.106:8080 | https://vpn.idahomesh.com | Meshtastic mesh VPN coordination |
| mesh-bridge | utility (CT 107) | 192.168.1.107 | Internal | Dual-tailscaled bridge (echo6 ↔ idahomesh) |
| MeshAI | utility (CT 108) | 192.168.1.144:4403 | Internal | LLM-powered Meshtastic assistant (Docker, Gemini Flash, Google grounding) |
| ARGUS | utility (CT 103) | 192.168.1.103 | Internal | OSINT intelligence gathering platform (Docker, SearXNG + local LLM analysis) |
| Authentik | edge2 (CT 105) | 100.64.0.36:9000 | https://auth.echo6.co | SSO provider (Echo6 branded, custom CSS, dark theme) — fronted by Contabo Caddy (reverse_proxy 100.64.0.36:9000); **migrated from Contabo 2026-06-18** |
| Forge (Forgejo) | edge2 (CT 103) | 100.64.0.34:3001 HTTP / :2222 SSH (via Contabo DNAT) | https://forge.echo6.co | Git server — fronted by Contabo Caddy (reverse_proxy 100.64.0.34:3001); git SSH via iptables DNAT on Contabo (forgejo-ssh-dnat.service) — **migrated from Contabo 2026-06-16** |
| Headscale | Contabo | 5.189.158.149 | https://vpn.echo6.co | Tailscale coordination (OIDC enabled) |
| Headplane | Contabo | 127.0.0.1:3100 | https://vpn.echo6.co/admin | Headscale web UI (OIDC via Authentik) |
| Mailcow | Contabo | 5.189.158.149 | https://mail.echo6.co | Email server |
| Vaultwarden | edge2 (CT 102) | 100.64.0.33:8086 | https://vault.echo6.co | Password manager (SSO enabled) — fronted by Contabo Caddy (reverse_proxy 100.64.0.33:8086) |
| Syncthing | Contabo | 100.64.0.1:22000 | Internal (Tailscale) | File sync — ~/.claude/, ~/projects/ |
| Syncthing | cortex | 100.64.0.14:22000 | Internal (Tailscale) | File sync — ~/.claude/, ~/projects/ |
| Proxmox VE | data node | 192.168.1.240:8006 | https://proxmox.echo6.co | Cluster web UI (via Caddy+Tailscale) |
| Immich | cloud (CT 120) | 192.168.1.182:2283 | https://immich.echo6.co | Photo management (Docker, NFS storage on pi-nas) |
| Nextcloud | cloud (CT 121) | 192.168.1.183:11000 | https://nextcloud.echo6.co | Cloud storage (AIO Docker, NFS on pi-nas, SSO) |
| Jellyfin | media (VM 105) | 192.168.1.160:8096 | https://jellyfin.echo6.co | Media server (Docker, NFS on pi-nas, SSO) |
| Jellyseer | media (VM 105) | 192.168.1.160:5055 | https://requests.echo6.co | Media request management (Docker, SSO) |
| Sonarr | media (VM 105) | 192.168.1.160:8989 | Internal | TV automation (Docker) |
| Radarr | media (VM 105) | 192.168.1.160:7878 | Internal | Movie automation (Docker) |
| Prowlarr | media (VM 105) | 192.168.1.160:9696 | Internal | Indexer manager (Docker) |
| SABnzbd | media (VM 105) | 192.168.1.160:8080 | Internal | Usenet download client (Docker) |
| PeerTube | media (CT 110) | 192.168.1.170:9000 | https://stream.echo6.co | Video streaming (native, NFS on pi-nas, SSO) |
| WATCHTOWER | **Decommissioned (2026-06-16)** | — | ~~wt.echo6.co~~ | Was Docker on Contabo `/opt/watchtower`; stopped & archived to forge.echo6.co/matt/archive-watchtower |
| Open WebUI | cortex (VM 150) | 192.168.1.150:8080 | https://ai.echo6.co | AI chat interface (Docker, Ollama backend, SSO) |
| Qdrant | cortex (VM 150) | 192.168.1.150:6333 | Internal | Vector database (Docker, RECON knowledge store) |
| TEI | cortex (VM 150) | 192.168.1.150:8090 | Internal | Text embeddings (Docker, bge-m3 1024-dim) |
| RECON | data (VM 1130) | 192.168.1.130:8420 | https://recon.echo6.co | Knowledge extraction pipeline (systemd, dashboard+API) |
| Files | data (VM 1130) | 192.168.1.130:8888 | https://files.echo6.co | PDF library (nginx, Authentik forward auth) |
| Samba | data | 192.168.1.240:445 | Internal | SMB file sharing — `//data/library` → /mnt/data/library (guest access) |
| Matrix Synapse | Contabo | 127.0.0.1:8008 | https://matrix.echo6.co | Matrix homeserver (Docker, SSO) |
| Element Web | Contabo | 127.0.0.1:8088 | https://element.echo6.co | Matrix web client (Docker) |
| mautrix-signal | Contabo | internal (29328) | DM @signalbot:echo6.co | Signal bridge (Docker, E2BE, MSC4190, double puppeting) |
| LiveSync | edge2 (CT 104) | 100.64.0.35:5984 (CouchDB) / :5985 (provisioner) | https://notes.echo6.co | Obsidian sync (CouchDB + provisioner, Docker, JWT auth) — fronted by Contabo Caddy (reverse_proxy 100.64.0.35:5984 / :5985); **migrated from Contabo 2026-06-16** |
| TAK Server | **Decommissioned (2026-06-16)** | — | ~~tak.echo6.co~~ | Was Docker on Contabo `/opt/tak-server-deploy`; stopped & archived to forge.echo6.co/matt/archive-tak-server |
| SIGIL | **Decommissioned (2026-06-16)** | — | ~~tak.echo6.co/sigil~~ | Was Docker on Contabo `/opt/sigil`; stopped & archived to forge.echo6.co/matt/archive-tak-server |
| OpenTAKServer (OTS) | utility (CT 109) | 192.168.1.109:443 | https://ots.k7zvx.com | Live TAK server (native install, nginx+RabbitMQ+PostgreSQL, Meshtastic MQTT gateway on port 8883) — see [[ots-setup]] |
| Echo6 Cortex Agent | cortex (VM 150) | N/A (Matrix bot) | #cortex:echo6.co in echo6-ops space | Claude Code bridge — @cortex:echo6.co, session continuity, E2EE (systemd) |
| Echo6 Contabo Agent | Contabo | N/A (Matrix bot) | #contabo:echo6.co in echo6-ops space | Claude Code bridge — @contabo:echo6.co, session continuity, E2EE (systemd) |
| mautrix-signal | Contabo | 29328 (internal) | Internal (matrix-net) | Signal bridge — @signalbot:echo6.co, E2BE, MSC4190, auto-portals |
| Matrix MAS | Contabo | 127.0.0.1:8085 | Internal (via Caddy) | Matrix Authentication Service (Docker, handles login/logout/OIDC for Synapse) |
| Termix | Contabo | 0.0.0.0:8083 | Internal (no Caddy block) | Terminal sharing tool (Docker, ghcr.io/lukegus/termix:latest) |
| Archivist | utility (CT 118) | 192.168.1.118 | Internal | Signal/Matrix room archive bot (systemd) — see archivist.md for details |
| pt-transcoder | cortex (VM 150) | N/A | Internal | PeerTube H.265 NVENC transcoder (systemd, /opt/bulk-import/transcoder.py) |
| recon-sparse | cortex (VM 150) | 192.168.1.150:8091 | Internal | RECON sparse embedding service (systemd, bge-m3 model, port 8091) |
| Samba | cortex (VM 150) | 192.168.1.150:445 | Internal | SMB file sharing — `//cortex/projects` → /home/zvx/projects (guest access) |
## Services by Server
### toc - Proxmox Host (192.168.1.244 / Tailscale: 100.64.0.13)
- Proxmox VE node (echo6-cluster)
- GPU passthrough host for cortex VM
- No direct services — workloads run on cortex VM
### cortex - VM 150 on toc (192.168.1.150 / Tailscale: 100.64.0.14)
- GPU compute VM (RTX A4000)
- Claude Code host
- Syncthing (syncs with Contabo)
- Open WebUI (port 8080, https://ai.echo6.co, Docker, SSO via Authentik, Echo6 theme)
- Compose path: `/opt/open-webui/docker-compose.yml`
- Echo6 theme: togglable via "E6" button (bottom-right), persisted in localStorage
- Theme files bind-mounted from `/home/zvx/echo6-theme/` into container
- DEFAULT_USER_ROLE=user (new signups auto-activated, not pending)
- Ollama (port 11434, internal, Docker with GPU)
- Qdrant (port 6333, internal, Docker — vector DB for RECON)
- TEI (port 8090, internal, Docker — bge-m3 embeddings for RECON)
- PeerTube remote runner (peertube-runner service, Whisper auto-captioning via smart GPU/CPU wrapper, concurrency=2, MemoryMax=20G)
- pt-transcoder (systemd: pt-transcoder.service, PeerTube H.265 NVENC transcoder)
- Script: `/opt/bulk-import/transcoder.py`
- MemoryMax=12G, Restart=always, RestartSec=60
- Depends on: nvidia-persistenced.service
- recon-sparse (systemd: recon-sparse.service, RECON sparse embedding service)
- Script: `/opt/recon-sparse/sparse_embed_service.py --port 8091`
- Model: BAAI/bge-m3 (HuggingFace cache)
- Restart=on-failure, RestartSec=10
- Samba (smbd/nmbd, system packages)
- Share: `//cortex/projects``/home/zvx/projects` (browseable, read-write, guest OK, force user/group zvx)
- Workgroup: WORKGROUP, standalone server
- Echo6 Cortex Agent (systemd: echo6-agent.service, matrix-nio bot, @cortex:echo6.co)
- Install path: `/opt/echo6-agent/`
- Matrix space: echo6-ops, room: #cortex:echo6.co (E2EE, private)
- Session continuity via `claude -p --resume`, persistent per-room sessions
- `!new` resets conversation session
- Allowed users: @matt:echo6.co
- MAS user ID: 01KKX88ARGK0BTA1JMB2QVAW4C
### utility - CT 100 (192.168.1.100 / Tailscale: 100.64.0.7)
- MeshMonitor (port 8080, https://mesh.echo6.co)
- Image: `meshmonitor:multichannel-new` (local build from zvx-echo6/meshmonitor fork, branch `feature/multi-channel-automation`)
- Fork of Yeraze/meshmonitor with multi-channel AutoAnnounce and AutoResponder support (PR #2078 open upstream)
### utility - CT 101 (192.168.1.101 / Tailscale: 100.64.0.8)
- Utility Caddy (reverse proxy for VPN-only services)
### utility - CT 102 (192.168.1.102 / Tailscale: 100.64.0.15)
- Echo6 Search — branded SearXNG homepage (port 8080, https://echo6.co)
- Custom cyberpunk theme: JetBrains Mono font, cyan/yellow palette, dark backgrounds
- Homepage: centered Echo6 logo + pill search bar (Google-style, viewport-locked no-scroll)
- Results page: full-width two-column grid (results + sidebar), stretched search header
- Top nav bar: `.//photos`, `.//mail`, waffle app launcher (11 services), login avatar
- All nav links use Authentik launch URLs for seamless SSO pass-through
- search.echo6.co permanently redirects to echo6.co (301)
- Redis/Valkey cache (valkey container)
- Compose path: `/opt/searxng/docker-compose.yml`
- Theme files: `/opt/searxng/custom/` (bind-mounted into container)
- `templates/simple/base.html` — custom template (nav, CSS, waffle menu, footer)
- `templates/simple/index.html` — custom homepage (Echo6 logo replaces SearXNG title)
- `img/echo6-logo.png` — Echo6 logo (replaces SearXNG logo)
- `img/favicon.png` — Echo6 favicon
- Config: `/opt/searxng/searxng-config/settings.yml` (instance_name: "Echo6", dark theme, center_alignment: false)
- SearXNG version: 2026.2.6 (Docker image: searxng/searxng:latest)
### utility - CT 108 (192.168.1.144 / Tailscale: 100.64.0.32)
- MeshAI — LLM-powered Meshtastic mesh assistant (Docker)
- Bot name: AIDA, node ID !27780c47, channel 8 whitelist
- Image: ghcr.io/zvx-echo6/meshai:latest (GitHub Actions multi-arch build)
- Backend: Gemini 2.5 Flash with Google Search grounding
- Connects to meshtasticd **on aida-nebra** (192.168.1.253:4403) — the AIDA-N2 node !27780c47
- Config TUI on port 7682 (`meshai --config`)
- Commands: !help, !ping, !status, !weather, !reset, !clear
- 7-day rolling conversation memory (SQLite), full history sent to LLM
- Response: 175 char chunks × 3 messages max
- Compose path: `/home/zvx/meshai/docker-compose.yml`
### utility - CT 118 (192.168.1.118)
- Signal/Matrix room archive bot (archivist.service via systemd)
- 1 core, 1GB RAM, 8GB disk
- Not registered in Headscale (no Tailscale)
- Source: forge.echo6.co/matt/matrix-archivist (private)
- See `/home/zvx/projects/.ref/docs/matrix/archivist.md` for implementation details
### cloud - CT 120 (192.168.1.182 / Tailscale: 100.64.0.2)
- Immich photo management (https://immich.echo6.co)
- Port 2283
- NFS storage from pi-nas (/mnt/immich)
- Compose path: `/opt/immich/docker-compose.yml`
### cloud - CT 121 (192.168.1.183 / Tailscale: 100.64.0.11)
- Nextcloud AIO (https://nextcloud.echo6.co)
- Apache port 11000, AIO management on 8080
- NFS storage from pi-nas (/mnt/nextcloud)
- SSO via Authentik OIDC
### media - VM 105 (192.168.1.160 / Tailscale: 100.64.0.18)
- ARR media automation stack (Docker)
- Jellyfin media server (port 8096, https://jellyfin.echo6.co)
- Jellyseer request management (port 5055, https://requests.echo6.co)
- Sonarr TV automation (port 8989, internal)
- Radarr movie automation (port 7878, internal)
- Prowlarr indexer manager (port 9696, internal)
- SABnzbd Usenet downloader (port 8080, internal)
- NFS storage from pi-nas (/mnt/arr)
- Config dirs: /opt/arr/{jellyfin,jellyseer,sonarr,radarr,prowlarr,sabnzbd}
### media - CT 110 (192.168.1.170 / Tailscale: 100.64.0.23)
- PeerTube video streaming (https://stream.echo6.co)
- Native install (Node.js 22, PostgreSQL 16, Redis, nginx)
- Port 9000 (PeerTube), proxied via nginx on port 80
- NFS storage from pi-nas (/var/www/peertube/storage, /export/peertube)
- SSO via Authentik OIDC (peertube-plugin-auth-openid-connect)
- Privileged container (NFS bind-mount)
- Auto-transcription enabled (remote runners on cortex, Whisper medium model)
- **PeerTube Bulk Import Pipeline:**
- pt-downloader.service — YouTube channel downloader (yt-dlp, sliding window, cookie auth)
- pt-importer.service — Uploads downloaded videos to PeerTube via resumable upload API
- NordVPN (nordvpnd.service) — IP rotation for downloads
- Config: `/opt/bulk-import/config/` (channel-map.json, cookies.txt, downloader-state.json)
- Logs: `/opt/bulk-import/logs/`
- Pipeline dirs: `/var/www/peertube/storage/pipeline/{staging,completed,transcoded,failed}`
### data - Proxmox Host (192.168.1.240 / Tailscale: 100.64.0.6)
- Proxmox VE node (echo6-cluster)
- Samba (smbd/nmbd, system packages)
- Share: `//data/library``/mnt/data/library` (browseable, read-write, guest OK, force user/group root)
- Workgroup: WORKGROUP, standalone server
### data - VM 1130 "recon-vm" (192.168.1.130 / Tailscale: 100.64.0.24)
- **Migrated from CT 130 (LXC) on 2026-04-19**
- OS: Ubuntu 24.04.4 LTS, kernel 6.8.0-110-generic
- Resources: 4 cores, 16GB RAM, 100GB disk
- Software: Docker 29.4.0, Python 3.12.3 (venv), Tailscale, nginx, sqlite3
- RECON knowledge extraction pipeline
- systemd services: `recon.service`, `recon-watchdog.service`, `kiwix.service`
- Dashboard + API on port 8420 (https://recon.echo6.co)
- nginx file server on port 8888 (https://files.echo6.co, Authentik forward auth)
- Kiwix-serve on port 8430 (ZIM library, 10 sources)
- Install: `/opt/recon/` (Python 3, Flask, venv)
- NFS mounts: pi-nas:/export/library → /mnt/library (PDF source), /mnt/nav, /mnt/kiwix
- Pipeline: Extract (PyPDF2→pdftotext→Tesseract→Gemini Vision) → Enrich (Gemini) → Embed (TEI/Qdrant)
- DB: SQLite (status), Qdrant on cortex:6333 (vectors)
- Backups: rsync to Contabo every 6hrs (concepts, text, DB, config), DB snapshot every 2hrs
- Config: `/opt/recon/config.yaml`, keys in `/opt/recon/.env`
- Docs: `/opt/recon/PROJECT-BIBLE.md`
- User: zvx (sudo, SSH key auth)
### utility - CT 106 (192.168.1.106)
- IdahoMesh Headscale (https://vpn.idahomesh.com)
- Container name: meshtastic-hs
- Manages meshtastic mesh VPN (separate from echo6 Headscale on Contabo)
- Users: malice, sidpatchy, nebra
### utility - CT 107 (192.168.1.107)
- mesh-bridge — dual tailscaled instance
- Bridges echo6 (100.64.0.0/10) ↔ idahomesh (100.100.0.0/16) networks
- NAT masquerade + subnet route advertisement
- Echo6 clients need `--accept-routes` to reach idahomesh devices
- iptables FORWARD rules must be BEFORE `ts-forward` jump (Tailscale drops cross-tailnet packets otherwise)
- Echo6 socket: `/run/tailscale/tailscaled.sock` (port 41641)
- IdahoMesh socket: `/var/run/tailscale-meshtastic/tailscaled.sock` (port 41642, tun=tailscale1)
- Rules persisted: `/etc/iptables/rules.v4` via `iptables-restore.service`
### pi-nas (192.168.1.245 / Tailscale: 100.64.0.21)
- OpenMediaVault NAS (https://nas.echo6.co)
- Port 80 (HTTP)
- Internet Archive CLI (`ia` v5.7.2) installed for archive.org uploads
### aida-nebra (192.168.1.253 / Tailscale: 100.64.0.9)
- **AIDA-N2(RPT,LLM)** — meshtasticd node `!27780c47` (short name: AIDA)
- Hardware: Nebra 2W SX1262 hat (ZebraHat config in `/etc/meshtasticd/config.d/`)
- Port: 4403 (default), firmware 2.7.19 (PORTDUINO/native)
- Role: CLIENT_BASE, position: 42.574, -114.607 (manual)
- MAC source: eth0 (derived MAC `00:bd:27:78:0c:47`)
- MeshAI bot (CT 108) connects to this node via TCP `localhost:4403` (Docker network)
- Service: `meshtasticd.service` (single instance, runs as user meshtastic)
- Config: `/etc/meshtasticd/config.yaml` + `/etc/meshtasticd/config.d/ZebraHat_2W.yaml`
- User: zvx, password auth (`sshpass -p '7redditGold' ssh zvx@aida-nebra`)
### mt-isr (192.168.1.141 / IdahoMesh: 100.100.0.5)
- Raspberry Pi Zero 2 W, Debian 13 (trixie), Waveshare ETH/USB HUB HAT
- No meshtasticd (G2 managed via WiFi TCP, not local daemon)
- Meshtastic Python CLI v2.7.7 in venv (`/home/isr/meshtastic-cli/`)
- Tailscale on IdahoMesh tailnet (vpn.idahomesh.com, nebra user)
- WiFi hotspot: ISR-MESH (192.168.4.0/24, PMF disabled for ESP32 compatibility)
- Station G2 radio connected via WiFi at 192.168.4.241, managed via TCP
- G2 config: Freq51 (ch0, psk=1A==) + MediumFast (ch1), MEDIUM_FAST preset, ch=51, txPower=11
- G2 gold config backup: `isr@192.168.1.141:~/backups/g2-gold-config.yaml`
- DNS bootstrap drop-in for tailscaled (reboot-safe)
- User: isr, password auth (see credentials)
### mt-burleybutte (192.168.1.185)
- meshtasticd (software Meshtastic node, Nebra 2W hat)
- Raspberry Pi OS, user bb
- Static MAC: A7:A1:30:79:BB:BB
- Tailscale registered on IdahoMesh Headscale (vpn.idahomesh.com) under malice user
### edge2 - CT 103 (10.10.10.21 / Tailscale: 100.64.0.34, node 46 `forgejo`)
- Forgejo git server (https://forge.echo6.co — **migrated from Contabo 2026-06-16**)
- Headscale node id 46, name `forgejo`, user `echo6`
- Compose path: `/opt/forgejo/docker-compose.yml`
- Containers: `forgejo` (codeberg.org/forgejo/forgejo:14) + `forgejo-db` (postgres:16-alpine)
- Volumes: `forgejo-data` (git repos, app.ini, SSH host keys) + `forgejo-db`
- HTTP: binds to `100.64.0.34:3001`; Contabo Caddy proxies here over tailnet (`reverse_proxy 100.64.0.34:3001`)
- SSH: `git@forge.echo6.co:2222` → Contabo iptables DNAT (systemd unit `forgejo-ssh-dnat.service`, enabled, reboot-persistent) → `100.64.0.34:2222` → container port 22; SSH host keys preserved (no client warning)
- Login via Authentik OIDC (auth.echo6.co) — unchanged
- DB: PostgreSQL 16 (forgejo_db container); 9 repos, 1 user verified at migration
- Source (Contabo `/opt/forgejo`) STOPPED but intact as cold rollback; rollback = `systemctl disable --now forgejo-ssh-dnat` + restore `/etc/caddy/Caddyfile.bak-preforge` + `systemctl restart caddy` + `docker compose up -d` on Contabo
### edge2 - CT 104 (10.10.10.22 / Tailscale: 100.64.0.35, node `livesync`)
- LiveSync Obsidian sync service (https://notes.echo6.co — **migrated from Contabo 2026-06-16**)
- Headscale hostname `livesync`, tailnet IP 100.64.0.35
- Compose path: `/opt/livesync/docker-compose.yml`
- Containers: `livesync-couchdb` (couchdb:3.4) + `livesync-provisioner` (custom image)
- Named volumes: `couchdb-data`, `provisioner-data`
- Bind mounts: `couchdb/local.ini`, `couchdb/local.d/` (incl. `jwt-keys.ini`)
- CouchDB binds to `100.64.0.35:5984`; provisioner binds to `100.64.0.35:5985`
- Contabo Caddy proxies `notes.echo6.co``reverse_proxy 100.64.0.35:5984` (CouchDB) + `reverse_proxy 100.64.0.35:5985` (provisioner); Authentik forward_auth on `/_provision`; Obsidian CORS preserved; Authentik outpost stays `127.0.0.1:9000`
- Auth: per-user JWT (ES512) via provisioner; databases: `cc-db`, `userdb-matt`
- Data: ~16 MB in couchdb-data
- Source on Contabo STOPPED but intact as cold rollback; `/etc/caddy/Caddyfile.bak-prelivesync` exists
- **Resources:** 2 cores / 1024 MB RAM / 512 MB swap / 8 GB rootfs on `local`; unprivileged; onboot; Docker
### edge2 - CT 105 (10.10.10.23 / Tailscale: 100.64.0.36, node 48 `authentik`)
- Authentik SSO platform (https://auth.echo6.co — **migrated from Contabo 2026-06-18**)
- Headscale node id 48, hostname `authentik`, tailnet IP 100.64.0.36
- Compose path: `/opt/authentik/docker-compose.yml`
- Containers: `authentik-server` + `authentik-worker` (ghcr.io/goauthentik/server:2025.12.4) + `authentik-postgres` (postgres:16); NO Redis
- Worker runs as user:root and has docker.sock bind-mount (manages embedded outposts)
- Binds to `100.64.0.36:9000`; Contabo Caddy proxies here over tailnet for both `auth.echo6.co` (catch-all + outpost path matcher) and `notes.echo6.co` outpost/forward_auth references
- `AUTHENTIK_SECRET_KEY` carried byte-for-byte (sessions stayed valid across cutover — users dropped straight in)
- Bind-mounts (data/media, branding, certs, custom-templates) migrated intact
- Email dep: mail.echo6.co (unchanged)
- DB: PostgreSQL 16 (`authentik-postgres` container); ~705 MB (~18 MB pg_dump)
- Source on Contabo STOPPED but intact as cold rollback; `/etc/caddy/Caddyfile.bak-pre-authentik` exists on Contabo
- Reboot-survival fix: systemd unit on CT 105 gates `docker compose up` on `tailscale-online` (Docker was racing Tailscale on boot, failing the bind to the tailnet IP)
- **Resources:** 2 cores / 4096 MB RAM / 512 MB swap / 20 GB rootfs on `local`; unprivileged; onboot; Docker
### edge2 - CT 102 (10.10.10.20 / Tailscale: 100.64.0.33, node 45 `vaultwarden`)
- Vaultwarden password manager (port 8086, https://vault.echo6.co, Docker)
- Headscale node id 45, name `vaultwarden`, user `echo6`
- Compose path: `/opt/vaultwarden/docker-compose.yml`; data: `./data/`
- Binds to tailnet IP `100.64.0.33:8086:80`; Contabo Caddy proxies here over tailnet
- SSO via Authentik (`SSO_ONLY=false` — local email+master-password login also works)
- Source (Contabo `/opt/vaultwarden`) STOPPED but intact as cold rollback; rollback = restore `/etc/caddy/Caddyfile.bak-prevault` + `systemctl restart caddy` + `docker compose up -d` on Contabo
- **Migrated from Contabo to edge2 CT 102 on 2026-06-16**
### Contabo VPS (5.189.158.149 / Tailscale: 100.64.0.1)
- ~~Authentik~~ — **migrated to edge2 CT 105 on 2026-06-18** (Caddy now proxies auth.echo6.co + notes.echo6.co outpost/forward_auth → 100.64.0.36:9000; source STOPPED at `/opt/authentik`, intact as cold rollback; `/etc/caddy/Caddyfile.bak-pre-authentik` exists)
- Forge (Git) — **migrated to edge2 CT 103 on 2026-06-16** (Caddy now proxies to 100.64.0.34:3001; SSH DNAT via forgejo-ssh-dnat.service)
- Headscale (mesh VPN)
- Mailcow (email)
- Vaultwarden — **migrated to edge2 CT 102 on 2026-06-16** (Caddy now proxies to 100.64.0.33:8086)
- Syncthing (syncs with cortex)
- ~~WATCHTOWER~~ — **decommissioned 2026-06-16** (was `/opt/watchtower`; archived to forge.echo6.co/matt/archive-watchtower; `wt.echo6.co` Caddy block + GoDaddy A record removed)
- Matrix Synapse homeserver (port 8008, https://matrix.echo6.co, Docker, SSO via Authentik)
- Element Web client (port 8088, https://element.echo6.co, Docker)
- mautrix-signal bridge (port 29328 internal, Docker, E2BE with MSC4190)
- Image: `dock.mau.dev/mautrix/signal:v0.2603.0`
- Container: `mautrix-signal` on `matrix-net`
- Config: `/opt/matrix/mautrix-signal/config.yaml`
- Registration: `/opt/matrix/synapse/registration.yaml` + `/opt/matrix/synapse/doublepuppet.yaml`
- Database: `mautrix_signal` on `matrix-postgres` (role: `mautrix_signal`, minimal grants)
- Bot user: `@signalbot:echo6.co`, device: `UPX4KKLZVY`
- Permissions: `@matt:echo6.co` = admin, `echo6.co` = user
- Double puppeting: appservice-based (doublepuppet.yaml as_token)
- Encryption: E2BE enabled (allow+default+require), MSC4190, self-signed cross-signing keys
- Compose path: `/opt/matrix/docker-compose.yml`
- Backup: daily at 3AM, 14-day retention (synapse + mas + mautrix_signal databases)
- ~~LiveSync~~ — **migrated to edge2 CT 104 on 2026-06-16** (source `/opt/livesync` STOPPED, intact as cold rollback; Caddy now proxies `notes.echo6.co``100.64.0.35:5984/5985`; `/etc/caddy/Caddyfile.bak-prelivesync` exists)
- ~~TAK Server~~ — **decommissioned 2026-06-16** (was `/opt/tak-server-deploy`; archived to forge.echo6.co/matt/archive-tak-server; `tak.echo6.co` Caddy block + GoDaddy A record removed)
- ~~SIGIL~~ — **decommissioned 2026-06-16** (was `/opt/sigil`; archived to forge.echo6.co/matt/archive-tak-server)
- Matrix Authentication Service (MAS) (port 8085, internal, Docker)
- Container: `matrix-mas` on `matrix-net`
- Handles login/logout/refresh/auth_metadata for Synapse
- Caddy routes: `/_matrix/client/*/login`, `/_matrix/client/*/logout`, `/_matrix/client/*/refresh`, `/_matrix/client/*/auth_metadata` → MAS (8085); `/_matrix/*` and `/_synapse/*` → Synapse (8008); default → MAS (8085)
- Compose: `/opt/matrix/docker-compose.yml` (shared with Synapse stack)
- Termix (port 8083, internal, Docker)
- Container: `termix` on `termix_default` network
- Image: `ghcr.io/lukegus/termix:latest`
- Port: 8080→8083 (bound to 0.0.0.0, NOT 127.0.0.1)
- Volume: `termix_termix-data``/app/data`
- No Caddy block — direct access only on port 8083
- Compose: `/opt/termix/` (inferred from Docker volume naming)
- ~~echo6-agent~~ — **decommissioned 2026-06-16** (was systemd `echo6-agent.service` at `/opt/echo6-agent/`; archived to forge.echo6.co/matt/archive-echo6-agent; unit disabled)
- ~~nexus-hub~~ + ~~nexus-agent~~**decommissioned 2026-06-16** (were systemd units at `/root/nexus-hub` and `/root/nexus-agent`; archived to forge.echo6.co/matt/archive-nexus-hub + archive-nexus-agent; units disabled)
- mautrix-signal bridge (mautrix-signal container, port 29328 internal)
- Image: dock.mau.dev/mautrix/signal:v0.2603.0
- Config: `/opt/matrix/mautrix-signal/config.yaml`
- Compose: `/opt/matrix/docker-compose.yml` (shared with Synapse stack)
- DB: mautrix_signal on matrix-postgres
- Bot: @signalbot:echo6.co, management room !fDjIRTMjxILVQoAcEN:echo6.co
- E2BE enabled (MSC4190), double puppeting via doublepuppet.yaml
- Signal account: +12083080811 (@matt:echo6.co)
- Portals auto-create on incoming messages (no autocreate toggle available)
- Ref: `/home/zvx/projects/.ref/docs/matrix/mautrix_signal.md`
## Decommissioned Services
Services stopped, archived, and removed from Caddy/DNS as of their decommission date. On-disk dirs on Contabo retained until edge1 rebuild wipes them.
| Service | Decommissioned | Archive Repo | Notes |
|---------|---------------|-------------|-------|
| TAK Server | 2026-06-16 | forge.echo6.co/matt/archive-tak-server | Was Docker `/opt/tak-server-deploy` on Contabo; `tak.echo6.co` Caddy block + GoDaddy A record removed |
| SIGIL | 2026-06-16 | forge.echo6.co/matt/archive-tak-server | Was Docker `/opt/sigil` on Contabo; served at `tak.echo6.co/sigil` |
| WATCHTOWER | 2026-06-16 | forge.echo6.co/matt/archive-watchtower | Was Docker `/opt/watchtower` on Contabo; `wt.echo6.co` Caddy block + GoDaddy A record removed |
| echo6-agent | 2026-06-16 | forge.echo6.co/matt/archive-echo6-agent | Was systemd unit at `/opt/echo6-agent/` on Contabo; unit disabled |
| nexus-hub | 2026-06-16 | forge.echo6.co/matt/archive-nexus-hub | Was systemd unit at `/root/nexus-hub` on Contabo; unit disabled |
| nexus-agent | 2026-06-16 | forge.echo6.co/matt/archive-nexus-agent | Was systemd unit at `/root/nexus-agent` on Contabo; unit disabled |
## Adding New Services
When deploying a new service, update this file with:
1. Service name
2. Host location (server + container if applicable)
3. IP:Port
4. Access method (internal only vs public URL)
5. Brief description
## Naming Conventions
- **Internal services:** Access via Tailscale IP (100.64.x.x) or local IP
- **Public services:** Access via `*.echo6.co` subdomain through Caddy reverse proxy
### Lidarr on Steroids (lidarr.echo6.co)
- **Container:** lidarr (youegraillot/lidarr-on-steroids:latest)
- **Host:** media VM 105 (192.168.1.160)
- **Ports:** 8686 (Lidarr), 6595 (Deemix)
- **Network:** arr-net
- **Config:** /opt/arr/lidarr/config (Lidarr), /opt/arr/lidarr/config_deemix (Deemix)
- **Compose:** /opt/arr/docker-compose.yml
- **Music root:** /mnt/arr/music (NFS from pi-nas)
- **Downloads:** /mnt/arr/downloads (shared with SABnzbd)
- **API key:** 78f026ec93a94d8eb3177816b74a57b7
- **Caddy:** lidarr.echo6.co -> 100.64.0.18:8686 (Authentik forward auth)
- **Prowlarr:** fullSync configured
- **SABnzbd:** configured (music category)
- **Deemix:** port 6595, NOT exposed via Caddy (Tailscale-only access)
- **PUID/PGID:** 1000/1000, TZ: America/Boise
### Navidrome (navidrome.echo6.co)
- **Container:** navidrome (deluan/navidrome:latest)
- **Host:** media VM 105 (192.168.1.160)
- **Port:** 4533
- **Network:** arr-net
- **Data volume:** arr_navidrome-data (named Docker volume)
- **Music volume:** /mnt/arr/music (read-only, shared with Lidarr)
- **Compose:** /opt/arr/docker-compose.yml
- **Caddy:** navidrome.echo6.co -> 100.64.0.18:4533 (Authentik forward auth)
- **User:** 1000:1000
- **Scan schedule:** every 1 hour
- **Admin setup:** First login at https://navidrome.echo6.co creates admin account