docs: restructure around source-of-truth pages
- CONTEXT.md glossary - README reduced to intro, quickstart and doc index - new architecture.md, gateway.md (from proxy-key-onboarding.md), operations.md; network-access.md rewritten - coding-cli-setup: stale OMNIROUTE_PORT:-4000 endpoint, terms and duplicated per-slot/classifier explanations fixed - research/README.md index; proxy-request-priority.md moved there as superseded Every doc names keys instead of restating values and links its source. Refs #55 (#56, #57, #59, #60) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
072eeb78c2
commit
a0e5e9704b
14 files changed
+340
-119
No files matched your search
+19
-14
@@ -1,24 +1,29 @@
|
||||
# Network access: proxy-ai.home / proxy-ai.haylan.ch
|
||||
# Network access
|
||||
|
||||
This stack has no chat UI — every client is a coding CLI reaching the AI gateway (OmniRoute). It doesn't run its own reverse proxy — it publishes the gateway's API port to the host and relies on the **existing Nginx Proxy Manager (NPM)** instance already fronting other self-hosted services on this network.
|
||||
> **Source of truth:** [`docker-compose.yml`](../docker-compose.yml) → the `ports:` / `expose:` entries of each service. This page explains *who can reach what, and why*; port numbers live in the source. If they disagree, the source wins.
|
||||
|
||||
## llama.cpp's raw API stays LAN-only — deliberately
|
||||
Terms as defined in [`CONTEXT.md`](../CONTEXT.md). The stack doesn't run its own reverse proxy. The existing **reverse proxy** (Nginx Proxy Manager, not part of this stack) publishes the gateway under hostnames.
|
||||
|
||||
The inference API (port `${LLAMA_PORT:-8080}`) is **not** registered in NPM and is **not** reachable externally. It has no authentication of its own — putting it on the public internet would mean an unauthenticated inference endpoint. Coding-agent CLIs (Claude Code, Kimi, OpenCode, Qwen Code — see `docs/coding-cli-setup/`) don't reach it directly at all now; they go through the gateway below, same as everything else.
|
||||
| What | Reachable from |
|
||||
|---|---|
|
||||
| Gateway API | LAN, and the internet via the reverse proxy |
|
||||
| Gateway dashboard | LAN only |
|
||||
| Backends | Stack network only (through the gateway) |
|
||||
| qdrant | The server itself only |
|
||||
|
||||
If you later want external CLI access too, that's a deliberate scope change — see the map ([issue #1](https://git.arthurerlich.de/haylan/LLM-Server/issues/1)) before doing it, since it changes the security posture.
|
||||
## Gateway
|
||||
|
||||
## The AI gateway (OmniRoute) — `proxy-ai.home` / `proxy-ai.haylan.ch`
|
||||
- **API port (`OMNIROUTE_API_PORT`)**: published on the server's LAN address. Two reverse-proxy hosts point at it:
|
||||
- `proxy-ai.home`: LAN only.
|
||||
- `proxy-ai.haylan.ch`: internet, through the DMZ that already forwards to the reverse proxy, which also manages the TLS certificate.
|
||||
|
||||
As of [issue #31](https://git.arthurerlich.de/haylan/LLM-Server/issues/31) (migrated from LiteLLM), the gateway is OmniRoute:
|
||||
Every call needs an [API key](gateway.md#api-keys), so the reverse proxy adds no auth of its own.
|
||||
- **Dashboard port (`OMNIROUTE_DASHBOARD_PORT`)**: published on the LAN only. It's never registered in the reverse proxy and has no port-forward, so it isn't reachable from the internet. Keep it that way: the dashboard manages every API key.
|
||||
|
||||
- **`proxy-ai.home`** and **`proxy-ai.haylan.ch`** both point only at `${OMNIROUTE_PORT:-4000}` — the API port. Set up as two NPM Proxy Hosts pointing at this machine's LAN IP on that port; `proxy-ai.home` internal-only, `proxy-ai.haylan.ch` external via the DMZ already forwarding to NPM (let NPM issue/manage the TLS cert as usual).
|
||||
- The **dashboard** (`${OMNIROUTE_DASHBOARD_PORT:-20128}`) is never registered in NPM at all, and `docker-compose.yml` never publishes that port to the host either — it manages every workload's keys, so it doesn't belong on the public internet, same reasoning as LiteLLM's old `/ui`. Unlike LiteLLM, OmniRoute's split-port mode means this is structural (no network route exists) rather than an NPM path-deny rule that has to be maintained and could be misconfigured. Reach the dashboard only from the host itself or over SSH port-forward.
|
||||
## Backends
|
||||
|
||||
**Every gateway call already requires a valid API key** (Bearer token, see `docs/proxy-key-onboarding.md`), so no extra NPM-level auth is needed for the external hostname.
|
||||
`llama-server` and `qwen-classifier` publish no host port (`expose` only). They have no authentication, so they're reachable only on the stack's Docker network, through the gateway. Making them directly reachable would put an unauthenticated inference endpoint on the network. That's a deliberate security change, not a config tweak.
|
||||
|
||||
## RAG knowledge graph (Neo4j) — `knowledge.proxy-ai.home`
|
||||
## qdrant
|
||||
|
||||
Set up as an NPM Proxy Host pointing at this machine's LAN IP on Neo4j's Browser port (`7474`, see `docker-compose.yml`'s `neo4j` service, [PR #50](https://git.arthurerlich.de/haylan/LLM-Server/pulls/50)). Internal-only, same as `proxy-ai.home` — no DMZ/external route, this is admin/dev tooling, not a client-facing endpoint. Bolt (`7687`, the actual query protocol) isn't proxied through NPM at all — clients on the LAN reach it directly at `<this-machine>:7687`.
|
||||
|
||||
Qdrant's dashboard (`6333`) stays on its raw LAN IP/port for now — no hostname assigned yet.
|
||||
Bound to the server's loopback interface, because qdrant has no authentication. From another machine, use an SSH port-forward to the server.
|
||||
Reference in new issue
Block a user