# Delta service map

This is an observed topology snapshot from 2026-07-30, not desired-state configuration. Refresh with `../scripts/fleet-snapshot.sh` and the owning Compose or systemd files before acting.

## Deployment root

Use `/home/delta/apps` for services that run from a Git clone or a directory containing Docker or Docker Compose files. Give each service its own directory under that root.

Before moving a running service there, verify its Compose project name, named volumes, bind mounts, relative paths, restart behavior, and route ownership. Move it only when a path-only relocation preserves all state. Leave a legacy service in place and report the reason when moving it would require deleting, resetting, or rewriting state.

## Host health at snapshot

- Debian 13 kernel `6.12.94+deb13-amd64`; host uptime approximately three weeks.
- Root filesystem: 503 GB total, 197 GB used, 286 GB available (41% used).
- Docker, Tailscale, OpenSSH, ClickHouse, Islandflow NATS, and Islandflow Redis were active.
- Two failed units were present: `cockpit.socket` and the transient test unit `hermes-webui-checkout-restart.service`. A failed unit does not prove its main service is down.
- `jq` was not installed on Delta; use Node, Python, or parse on Lavender.

## Native and user systemd workloads

| Layer | Units / role | Observed exposure |
|---|---|---|
| Native data plane | `clickhouse-server`, `islandflow-clickhouse`, `islandflow-nats`, `islandflow-redis` | Primarily loopback: ClickHouse `8123`; NATS `4222`/`8222`; Redis `6379` |
| Islandflow app | `islandflow-web`, `islandflow-api`, `islandflow-candles`, `islandflow-compute`, `islandflow-ingest-equities`, `islandflow-ingest-news`, `islandflow-ingest-options` | Web `3000`; API on Docker bridge `172.18.0.1:4000`; workers have no intended public listener |
| Hermes and automation | `hermes-gateway`, `hermes-webui`, `hermes-hudui`, `hermes-hudui-auth`, `pr-reviewer`, `signal-cli`, `t3code`, `t3code-orchestrator-preview`, `t3-npm-tailserve-relay` | Loopback application listeners include `3001`, `3002`, `7583`, `8080`, `8443`, `8787`, and `13773`; verify unit ownership live |
| Connectivity | `cloudflared-git-web`, `syncthing`, `tailscaled`, `ssh` | Cloudflare tunnel; Syncthing `8384` loopback and `22000`; SSH `22`; Tailscale Serve `5733`, `9443`, and `9444` |

Tailscale Serve maps:

- `https://deltaisland.shrew-mimosa.ts.net:5733/` to `http://127.0.0.1:5733` for the T3 orchestrator preview.
- `https://deltaisland.shrew-mimosa.ts.net:9443/` to `http://127.0.0.1:8443` for T3 Code.
- `https://deltaisland.shrew-mimosa.ts.net:9444/` to `http://127.0.0.1:3002` for the authenticated Hermes HUD.

## Docker workloads

| Compose project or standalone workload | Containers / role | Exposure at snapshot |
|---|---|---|
| `dirtypages` | `dirtypages-service-1` | Internal `3000`, healthy, proxied by NPM |
| `dirtynotes-temp` | `dirtynotes-temp` | Internal `3000`, healthy, proxied by NPM |
| `docker` | `freedomtracker` | Internal `3000`, proxied by NPM |
| `dream-crates` | API and poller | API bound on `8000`, also proxied by NPM |
| `drucquerdotcom` | `drucquer-web` | Internal `8080`, proxied by NPM |
| `forgejo` | Forgejo | Git SSH `2222`; web internal `3000` |
| `forgejo-runner` | Runner plus Docker-in-Docker | Internal runner network |
| `freshrss` | FreshRSS and `projectzero-feed-proxy` | FreshRSS internal `80`, proxied by NPM; feed proxy uses the shared NPM network |
| `netdata` | Netdata | Tailnet-bound `100.87.130.79:19999` |
| `nextcloud` | App, cron, MariaDB, Redis, Portainer | App and Portainer proxied; DB and Redis internal |
| `nginx-proxy-manager` | Public reverse proxy | Public-IP `80`/`443`; admin `81` bound to all interfaces |
| `qbittorrent` | qBittorrent | Peer port `6881`; web UI internal `8080` and proxied |
| `satisfactory-server` | Satisfactory game server | Host `7777` TCP/UDP and `8888` TCP |
| `stremio-server` | Stremio server | Internal `11470`/`12470`, proxied |
| standalone | `dirtydash`, `dolt-beads-server`, `hermes-tailnet-proxy` | Dirtydash proxied; Dolt loopback `3307`; Hermes proxy uses host networking |

All listed containers were running. Dirtypages, Dirty Notes, Satisfactory, Forgejo, FreedomTracker, Drucquer, and Netdata reported healthy; many other images did not define Docker health checks.

## Nginx Proxy Manager routes

Enabled routes observed:

| Host | Upstream |
|---|---|
| `*.pages.dirtydishes.dev`, `index.pages.dirtydishes.dev` | `dirtypages-service:3000` |
| `cloud.dpdrm.com` | `nextcloud-app:80` |
| `dirtydash.dirtydishes.dev` | `dirtydash:4599` |
| `dolt.deltaisland.io` | `172.18.0.1:8081` |
| `drucquer.com` | `drucquer-web:8080` |
| `flow.deltaisland.io` | `172.18.0.1:3000` |
| `git.dirtydishes.dev` | `forgejo:3000` |
| `kellan.drucquer.com` | `freedomtracker:3000` |
| `news.deltaisland.io` | `freshrss:80` |
| `notes.drucquer.com` | `dirtynotes-temp:3000` |
| `portainer.deltaisland.io` | `portainer:9000` |
| `proxy.deltaisland.io` | `nginx-proxy-manager:81` |
| `qb.deltaisland.io` | `qbittorrent:8080` |
| `samples.dpdrm.com` | `dream-crates-api-1:8000` |
| `stats.deltaisland.io` | `netdata:19999` |
| `stremio.dpdrm.com` | `stremio-server:11470` |
| `t3.dirtydishes.dev` | local T3 relay |

Disabled routes observed: `api.flow.deltaisland.io` and `hermes.deltaisland.io`. A disabled NPM route does not prove the underlying service is stopped.

## Ownership commands

Use the owning layer rather than killing processes directly:

```sh
systemctl status <native-unit>
systemctl --user status <user-unit>
journalctl --user -u <user-unit> --since '-15 min' --no-pager
docker compose -f <compose-file> ps
docker compose -f <compose-file> logs --since 15m <service>
ss -lntp
tailscale serve status --json
```

Query NPM's SQLite database read-only if route ownership matters. Select only domain, upstream, and enabled fields; do not dump users, access lists, certificates, or settings.
