# NPMPlus — reverse proxy + Let's Encrypt [NPMPlus](https://github.com/ZoeyVid/NPMPlus) (fork nginx-proxy-manager) exposes backend services on **HTTPS** with automatic certificates. On this host it proxies **LocalAI** at `https://llm.rtx1.mobile.agency-ai.dev` → `http://127.0.0.1:8070`. ## Ports (host network) | Port | Protocol | Service | |------|----------|---------| | 80 | tcp | HTTP (ACME challenge + redirects) | | 443 | tcp, udp | HTTPS / HTTP3 | | 81 | tcp | NPMPlus admin UI (HTTPS) | ## Prerequisites 1. `/data` mounted (tutorial 04) 2. DNS `A` record: `llm.rtx1.mobile.agency-ai.dev` → public IP 3. Router port forward: `80`, `443/tcp`, `443/udp` → `192.168.100.5` 4. `ACME_EMAIL` in `.env` (Let's Encrypt notifications) ## Quick start ```bash cd stacks/npmplus cp .env.example .env # Edit ACME_EMAIL (and optionally INITIAL_ADMIN_*) ./scripts/start.sh ``` Admin UI: `https://:81` (default login `admin@example.org` unless `INITIAL_ADMIN_EMAIL` set). ## Admin access (LAN) Use **`https://192.168.100.90:81`** (or your LAN IP), **not** `http://`. | Symptom | Cause | |---------|-------| | `http://IP:81` does not load UI | Port 81 serves HTTPS only; HTTP returns 308 redirect | | Browser shows certificate error | Default cert has no SAN for IP; run cert regeneration (below) | | `docker ps` shows empty PORTS | Normal with `network_mode: host` — check with `ss -tlnp \| grep ':81'` | Regenerate admin cert with SAN for your LAN IP: ```bash sudo ./scripts/regenerate-admin-cert.sh ``` After regeneration, open `https://:81`, click through the self-signed cert warning once, then log in. ## Proxy host — LocalAI In NPMPlus UI → **Hosts** → **Proxy Hosts** → Add: | Field | Value | |-------|-------| | Domain | `llm.rtx1.mobile.agency-ai.dev` | | Scheme | `http` | | Forward hostname | `127.0.0.1` | | Forward port | `8070` | | SSL | Request new certificate, Force SSL, HTTP/2 | | Websockets | Enabled | Clients send `Authorization: Bearer ` (same key as in `stacks/localai/.env`). Test: ```bash curl -s https://llm.rtx1.mobile.agency-ai.dev/v1/models \ -H "Authorization: Bearer $LOCALAI_API_KEY" ``` ## Firewall ```bash sudo ./scripts/configure-firewall.sh ``` Restricts direct access to LocalAI (8070) and gpu-fan (8090); allows 80/443 for NPMPlus. ## Data Persistent files: `/data/apps/npmplus/` ## Related - LocalAI stack: [`../localai/README.md`](../localai/README.md) - Client handoff: [`../localai/coding-agent/APP-CLIENT-HANDOFF.md`](../localai/coding-agent/APP-CLIENT-HANDOFF.md) - Tutorial: [`../../manual-tutorial/07-npmplus-reverse-proxy.md`](../../manual-tutorial/07-npmplus-reverse-proxy.md)