Files
docs/infra/portmap.md
T
fkrebs 80647c1a6b monitoring: add pve-exporter to portmap
Proxmox VE metrics via prometheus-pve-exporter on CT 109 :9221.
monitor@pve!prometheus token with Monitor (read-only) role.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 04:32:37 +02:00

302 lines
16 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.
# Port Map — NUC 14 Docker Stacks
> **Reverse proxy**: [Zoraxy v3.3.2](http://192.168.1.4:8000) on `192.168.1.4:8000` (LXC 108)
> Wildcard cert `*.nuclide.systems` · source of truth: [`proxy/zoraxy/routes.json`](proxy/zoraxy/routes.json)
> Manage routes: `uv run scripts/zoraxy_sync.py [--apply|--prune|--list]`
## Port Scheme
| Range | Category |
|---|---|
| 3100 | Loki (log aggregation) |
| 9090 | Prometheus (monitoring) |
| 9091 | Grafana (monitoring) |
| 9100 | node-exporter (host metrics) |
| 12345 | Alloy (log agent UI) |
| 1000010999 | Infrastructure |
| 1100011999 | Security & Auth |
| 1200012999 | Media Immich |
| 1300013999 | Media Downloads / Arr |
| 1400014999 | AI Stack |
| 1500015999 | Documents |
| 1600016999 | Automation |
| 1700017999 | Notes & Bookmarks |
| 1800018999 | DevOps / Image Gen |
| 1900019999 | Tracking |
| 2000020999 | Storage Admin |
| 3000030999 | VPN Control |
---
## Monitoring — CT 109 ops (192.168.1.8)
| Port | Host | Service | Notes |
|---|---|---|---|
| [9090](http://192.168.1.8:9090) | CT 109 | Prometheus | LAN only; 90d retention |
| [3000](http://192.168.1.8:3000) | CT 109 | Grafana | LAN only; admin/tapirnase |
| [3100](http://192.168.1.8:3100) | CT 109 | Loki | LAN only; 30d retention; log aggregation |
| [9221](http://192.168.1.8:9221) | CT 109 | pve-exporter | Proxmox VE metrics; auth: `monitor@pve!prometheus` |
| [12345](http://192.168.1.8:12345) | CT 109 | Alloy (self) | agent UI; also runs on all other hosts at :12345 |
| 9100 | CT 109 | node-exporter | host-network, self-scrape |
| 9100 | CT 104 | node-exporter | standalone stack `/opt/stacks/monitoring/`; scraped by CT 109 |
Scrape targets (CT 109 Prometheus): `litellm` CT104:14000/metrics/ (bearer sk-tapirnase), `node-ct104` :9100, `node-ct109` :9100, `home-assistant` 192.168.1.60:8123/api/prometheus (HA token), `prometheus` self.
LiteLLM metrics: `litellm_settings.callbacks: ["prometheus"]` in `ai/litellm-config/config.yaml`.
**Alloy (log agent)**: deployed on all 12 hosts → ships to Loki at CT 109:3100.
- Docker hosts (CT 101/104/105/109/110/111/112/113): container at `/opt/stacks/alloy/`; reads Docker socket + journald
- Binary/systemd (CT 102/103/108 + nuc): `/etc/alloy/config.alloy`; reads journald only
- HA VM 100: pending — install Promtail add-on from `https://github.com/mdegat01/hassio-addons`; set Loki URL to `http://192.168.1.8:3100/loki/api/v1/push`
---
## Infrastructure (1000010999)
| Port | Service | Container | Public URL | Notes |
|---|---|---|---|---|
| [10000](http://192.168.1.40:10000) | Homepage | `homepage` | — | Dashboard, LAN only |
| [10001](http://192.168.1.40:10001) | Dozzle | `dozzle` | [dozzle.nuclide.systems](https://dozzle.nuclide.systems) | Log viewer |
| [10002](http://192.168.1.40:10002) | Arcane | `arcane` | [arcane.nuclide.systems](https://arcane.nuclide.systems) | Web IDE |
| [10003](http://192.168.1.40:10003) | Gotify | `gotify` | [gotify.nuclide.systems](https://gotify.nuclide.systems) | Push notifications |
| [10004](http://192.168.1.40:10004) | Garage S3 API | `garage` | [s3.nuclide.systems](https://s3.nuclide.systems) | FIXED 2026-05-21: proxied by Zoraxy with ACME TLS. Garage API accessible at `https://s3.nuclide.systems`. Internal: `http://garage:3900` |
| 10005 (127.0.0.1 only) | Garage Admin | `garage` | — | localhost only |
---
## Security & Auth (1100011999)
| Port | Service | Container | Public URL | Notes |
|---|---|---|---|---|
| [11001](http://192.168.1.40:11001) | Vaultwarden | `vaultwarden` | [vault.nuclide.systems](https://vault.nuclide.systems) | Password manager · Pocket-ID OIDC client created 2026-05-21; auth flow not yet configured |
> Pocket-ID **migrated from this CT to LXC 110** on 2026-05-20. See the [External Services](#external-services-not-on-nuc-docker) table below.
---
## Media Immich (1200012999)
| Port | Service | Container | Public URL | Notes |
|---|---|---|---|---|
| [12000](http://192.168.1.40:12000) | Immich | `immich_server` | [immich.nuclide.systems](https://immich.nuclide.systems) | Photos/videos |
| — | Immich Power Tools | `immich_power_tools` | [immich-tools.nuclide.systems](https://immich-tools.nuclide.systems) | Container-internal :3000, Zoraxy proxy |
---
## Media Downloads / Arr Stack (1300013999)
All arr-stack services run behind `vpn_gluetun` container network.
| Port | Service | Container | Public URL | Notes |
|---|---|---|---|---|
| [13001](http://192.168.1.40:13001) | RDTClient | `rdtclient` | — | LAN only |
| [13002](http://192.168.1.40:13002) | Prowlarr | `prowlarr` | — | LAN only |
| [13003](http://192.168.1.40:13003) | Audiobookshelf | `audiobookshelf` | [abs.nuclide.systems](https://abs.nuclide.systems) | |
| [13004](http://192.168.1.40:13004) | ShelfArr | `shelfarr` | — | LAN only |
| [13005](http://192.168.1.40:13005) | Flaresolverr | `flaresolverr` | — | Internal only |
| [30000](http://192.168.1.40:30000) | Gluetun VPN control | `vpn_gluetun` | — | HTTP control API |
---
## AI Stack (1400014999)
| Port | Service | Container | Public URL | Notes |
|---|---|---|---|---|
| [14000](http://192.168.1.40:14000) | LiteLLM | `litellm` | [ai.nuclide.systems](https://ai.nuclide.systems) | LLM proxy gateway |
| [14001](http://192.168.1.40:14001) | LobeHub | `lobehub` | [chat.nuclide.systems](https://chat.nuclide.systems) | Chat UI |
| [14002](http://192.168.1.40:14002) | Qdrant | `qdrant_scientific` | — | Vector DB, internal only |
| [8080](http://192.168.1.40:8080) | MCP Gateway | `mcp-gateway` | [mcp.nuclide.systems](https://mcp.nuclide.systems) | Pocket ID gated; spawns MCP servers on `ai-internal` |
| [18002](http://192.168.1.40:18002) | ComfyUI | `comfyui` | — | LAN only (Intel Arc iGPU, FLUX.1-schnell GGUF) |
| [18003](http://192.168.1.40:18003) | ComfyUI MCP | `comfyui-mcp` | — | FastMCP; reachable via gateway at `mcp.nuclide.systems/comfyui/mcp` |
| [18005](http://192.168.1.40:18005) | Docling MCP | `docling-mcp` | — | SAIA Docling PDF→Markdown; reachable via gateway |
| [18007](http://192.168.1.40:18007) | Kroki MCP | `kroki-mcp` | — | Diagram rendering; reachable via gateway |
| [18009](http://192.168.1.40:18009) | Speaches | `speaches` | — | TTS/STT; LAN only |
| ~~18010~~ | ~~Shepard MCP~~ | ~~`shepard-mcp`~~ | — | **DECOMMISSIONED 2026-05-21** — replaced by native `https://shepard.nuclide.systems/v2/mcp` (streamable HTTP; gateway entry: `shepard`, auth via `${SHEPARD_API_KEY}`) |
| [18011](http://192.168.1.40:18011) | Upload-artifact MCP | `upload-artifact-mcp` | — | S3 chat-artifacts upload; reachable via gateway |
| — | SearXNG | `searxng` | — | Internal, `shared_backend`, used by LobeHub |
---
## Documents (1500015999)
| Port | Service | Container | Public URL | Notes |
|---|---|---|---|---|
| [15000](http://192.168.1.40:15000) | Traccar HTTP | `traccar` | [traccar.nuclide.systems](https://traccar.nuclide.systems) | GPS tracking UI |
| [15001](http://192.168.1.40:15001) | Traccar GPS | `traccar` | — | TCP+UDP watch protocol |
| [15002](http://192.168.1.40:15002) | Paperless AI | `paperless-ai` | [paperless-ai.nuclide.systems](https://paperless-ai.nuclide.systems) | Internal-only Zoraxy policy |
| [15003](http://192.168.1.40:15003) | Paperless-ngx | `paperless-ngx-webserver-1` | [paperless.nuclide.systems](https://paperless.nuclide.systems) | Internal-only Zoraxy policy |
---
## Automation (1600016999)
| Port | Service | Container | Public URL | Notes |
|---|---|---|---|---|
| [16000](http://192.168.1.40:16000) | n8n | `n8n` | [n8n.nuclide.systems](https://n8n.nuclide.systems) | Workflow automation |
---
## Notes & Bookmarks (1700017999)
| Port | Service | Container | Public URL | Notes |
|---|---|---|---|---|
| [17000](http://192.168.1.40:17000) | Memos | `memos` | [memos.nuclide.systems](https://memos.nuclide.systems) | Notes |
| [17001](http://192.168.1.40:17001) | Karakeep | `karakeep` | [hoarder.nuclide.systems](https://hoarder.nuclide.systems) | Bookmarks |
---
## DevOps (1800018999)
| Port | Service | Container | Public URL | Notes |
|---|---|---|---|---|
<!-- Daytona DECOMMISSIONED 2026-05-20; replaced by Coder on CT 111. Compose renamed *.DECOMMISSIONED-2026-05-20. -->
| — | MCP servers (Gitea repos) | See AI Stack §18000 | — | `mcp-comfyui`, `mcp-docling`, `mcp-upload-artifact` at `git.nuclide.systems/fkrebs/` (`mcp-shepard` decommissioned) |
---
## Tracking (1900019999)
_Traccar moved to 1500015001 (Documents range). 1900019001 now free._
---
## Storage Admin (2000020999)
| Port | Service | Container | Public URL | Notes |
|---|---|---|---|---|
| 20010 (127.0.0.1 only) | pgAdmin | `pgadmin` | — | shared-db pgAdmin, localhost only (CT 104) |
---
## LXC 112 — secrets (`192.168.1.7`)
CT 112 hosts Infisical. **LAN-only — no Zoraxy route; secrets must not be internet-exposed.**
| Port | Service | Container | Notes |
|---|---|---|---|
| 8200 | Infisical | `infisical` | LAN: `http://192.168.1.7:8200` — admin UI + API |
| (internal) | Postgres 16 | `infisical-db` | DB for Infisical only; no external port |
| (internal) | Redis 7 | `infisical-redis` | Session/queue backing; no external port |
Stack at `/opt/stacks/infisical/` on CT 112. Deployed 2026-05-22.
---
## LXC 113 — db (`192.168.1.6`)
CT 113 is the dedicated postgres LXC. No public proxy routes — LAN access only.
| Port | Service | Container | Notes |
|---|---|---|---|
| 5432 | Postgres 17 | `postgres` | LAN: `192.168.1.6:5432` — accepts app connections from all CTs |
| 5050 | pgAdmin 4 | `pgadmin` | LAN only: `http://192.168.1.6:5050` — no Zoraxy route |
---
## LXC 111 — Dev (`192.168.1.42`)
CT 111 hosts the self-hosted dev platform. Same Pocket-ID SSO as the rest.
| Port | Service | Container | Public URL | Notes |
|---|---|---|---|---|
| [7080](http://192.168.1.42:7080) | Coder | `coder` | [dev.nuclide.systems](https://dev.nuclide.systems) | Workspace orchestrator; OIDC via Pocket-ID; password auth disabled |
| [3000](http://192.168.1.42:3000) | Gitea | `gitea` | [git.nuclide.systems](https://git.nuclide.systems) | Self-hosted Git; OIDC; password form disabled |
| [222](http://192.168.1.42:222) | Gitea SSH | `gitea` | — | `ssh -p 222 git@git.nuclide.systems` |
| 5432 (internal) | coder-db | `coder-db` | — | Postgres 16 for Coder |
| 5432 (internal) | gitea-db | `gitea-db` | — | Postgres 16 for Gitea |
| [13080](http://192.168.1.42:13080) | docs site | `docs-server` | — (LAN-only) | mkdocs Material; auto-rebuilds from `fkrebs/docs` every 5 min |
| (no port) | coder-fkrebs-dev | (workspace) | (Coder app proxy) | Active Coder workspace |
| (no port) | act-runner | `act-runner` | — | Gitea Actions runner (`ct111-runner`) |
---
## QNAP TS-251D (`192.168.1.189`)
Celeron J4025, 2-core. Hosts Klipper natively (not Docker).
| Port | Service | Notes |
|---|---|---|
| 80 | Mainsail | 3D printer web UI |
| 7125 | Moonraker | Klipper API |
Config backed up daily to `git.nuclide.systems/fkrebs/klipper-config` via cron at 03:00 → covered offsite by Backrest `services/gitea` path.
---
## External Services (Not on NUC Docker)
Zoraxy routes to these external backends:
| Domain | Target | Host | Service |
|---|---|---|---|
| [ha.nuclide.systems](https://ha.nuclide.systems) | `192.168.1.60:8123` | Home Assistant VM 100 | Home automation |
| [nc.nuclide.systems](https://nc.nuclide.systems) | `192.168.1.41:11000` | Nextcloud LXC 105 | Cloud storage |
| [ocpp.nuclide.systems](https://ocpp.nuclide.systems) | `192.168.1.60:8887` | Home Assistant VM 100 | EV charger OCPP |
| [shepard.nuclide.systems](https://shepard.nuclide.systems) | `192.168.1.49:80` | Shepard LXC 101 | Shepard |
| [shepard-api.nuclide.systems](https://shepard-api.nuclide.systems) | `192.168.1.49:8080` | Shepard LXC 101 | Shepard API |
| [id.nuclide.systems](https://id.nuclide.systems) | `192.168.1.5:11000` | Pocket-ID LXC 110 | OIDC IdP (migrated 2026-05-20) |
| [git.nuclide.systems](https://git.nuclide.systems) | `192.168.1.42:3000` | Dev LXC 111 | Gitea (self-hosted Git) |
| [dev.nuclide.systems](https://dev.nuclide.systems) | `192.168.1.42:7080` | Dev LXC 111 | Coder (workspace orchestrator) |
| Gitea SSH | `192.168.1.42:222` | Dev LXC 111 | `ssh -p 222 git@git.nuclide.systems` |
---
## Zoraxy Public Routes (proxied via `192.168.1.4`)
| Domain | Backend (NUC `192.168.1.40`) | Port |
|---|---|---|
| [ai.nuclide.systems](https://ai.nuclide.systems) | litellm | 14000 |
| [chat.nuclide.systems](https://chat.nuclide.systems) | lobehub | 14001 |
| [mcp.nuclide.systems](https://mcp.nuclide.systems) | mcp-gateway | 8080 |
| [arcane.nuclide.systems](https://arcane.nuclide.systems) | arcane | 10002 |
| [gotify.nuclide.systems](https://gotify.nuclide.systems) | gotify | 10003 |
| [vault.nuclide.systems](https://vault.nuclide.systems) | vaultwarden | 11001 |
| [immich.nuclide.systems](https://immich.nuclide.systems) | immich_server | 12000 |
| [immich-tools.nuclide.systems](https://immich-tools.nuclide.systems) | immich_power_tools | (container-internal) |
| [abs.nuclide.systems](https://abs.nuclide.systems) | audiobookshelf | 13003 |
| [n8n.nuclide.systems](https://n8n.nuclide.systems) | n8n | 16000 |
| [memos.nuclide.systems](https://memos.nuclide.systems) | memos | 17000 |
| [hoarder.nuclide.systems](https://hoarder.nuclide.systems) | karakeep | 17001 |
| [traccar.nuclide.systems](https://traccar.nuclide.systems) | traccar | 15000 |
| [dozzle.nuclide.systems](https://dozzle.nuclide.systems) | dozzle | 10001 |
| [s3.nuclide.systems](https://s3.nuclide.systems) | garage | 10004 |
**Not publicly proxied** (LAN / localhost only): pgadmin, paperless, paperless-ai, comfyui, comfyui-mcp, rdtclient, prowlarr, shelfarr, qdrant.
---
## Known Issues
- **`lobe-postgres` / `lobe-redis`**: host-port exposed (`0.0.0.0:5432/6379`) — firewall blocks external access but ideally restricted to localhost.
---
## OIDC Client Registry (Pocket ID — `id.nuclide.systems`)
| Client ID | Name | Redirect URIs |
|---|---|---|
| `e73bb7b9` | litellm | (empty = accept all) — used by LiteLLM UI + MCP Gateway |
| `26f3c26b` | lobehub | `https://chat.nuclide.systems/api/auth/callback/generic-oidc` |
| `81cf4ed0` | arcane | `https://arcane.nuclide.systems/auth/oidc/callback` |
| `33135ad4` | n8n | `https://n8n.nuclide.systems/auth/oidc/callback` |
| `9c91c18b` | immich | `https://immich.nuclide.systems/auth/login` + mobile |
| `62bf4e0d` | memos | `https://memos.nuclide.systems/auth/callback` |
| `d92f82b0` | karakeep | `https://hoarder.nuclide.systems/api/auth/callback/custom` |
| `a14b8076` | nextcloud | `https://nc.nuclide.systems/apps/user_oidc/code` |
| `0aee4280` | Coder | `https://dev.nuclide.systems/api/v2/users/oidc/callback` |
| `9444609e` | Gitea | `https://git.nuclide.systems/user/oauth2/pocket-id/callback` |
| `38469e7e` | Proxmox VE | `https://192.168.1.20:8006` |
| ~~798a367f~~ | ~~daytona~~ | **DECOMMISSIONED — remove from Pocket-ID** |
| `cbbf20d5` | Audiobookshelf | `https://abs.nuclide.systems/…` + `*` |
| `d8733fcc` | shelfarr | `*` |
| `78c78998` | Claude MCP | `https://claude.ai/api/mcp/auth_callback` + `https://mcp.nuclide.systems/mcp/auth/callback` |
| `82ca2d53` | nuc-ai | (empty) — used by spawned MCP servers |
| `7fe1a14b` | zoraxy | (empty) |
| `af2f837b` | mcp-auth | (empty) — legacy, unused |
| (new) | vaultwarden | `https://vault.nuclide.systems/auth/callback` | Created 2026-05-21; SSO wiring deferred |
**OIDC Endpoints** (corrected 2026-05-17 — previously used wrong `/api/v1/oauth2/` path):
- Authorization: `https://id.nuclide.systems/authorize`
- Token: `https://id.nuclide.systems/api/oidc/token`
- Userinfo: `https://id.nuclide.systems/api/oidc/userinfo`
- Discovery: `https://id.nuclide.systems/.well-known/openid-configuration`