feat(open-notebook): put the podcast generator behind the guard chain
The service came up internal-only: UI on the LAN at 8502, API at 5056, both published on every interface, with only its own shared password in front. That put the episode library outside the fleet's auth chain and one port scan away from anything on the network. - Caddy: guarded vhost notebook.franksdank.cloud (Anubis -> Authentik; provider notebook-proxy, internal_host caddy:8017) plus the post-auth route to the published UI port. One upstream is enough, because the image's own Next.js layer rewrites /api/* to the FastAPI beside it — so the API needs no outward face at all, and 5056 moves to loopback, where only the deployer's health gate dials it. - scripts/open-notebook.env: API_URL and CORS_ORIGINS become the single guarded origin. Left to itself the app auto-detects <host>:5055, the port seerr holds on this host; a LAN-origin API_URL would also take the browser around the guard chain, where its authenticated session does not ride. - addn-hosts: the LAN A record. The homepage card goes live and links the vhost. - Seam: the API origin is derived from whatever the Caddyfile routes to 8502, so renaming the vhost moves the test instead of leaving it blessing a stale name, and a new test proves the vhost hands the WHOLE request to Anubis.
This commit is contained in:
+16
-10
@@ -1,5 +1,6 @@
|
||||
# open-notebook.env — configuration for **open-notebook**, the fleet's podcast
|
||||
# generator on Dankclaw (UI host port **8502**, API host port **5056**). Read by
|
||||
# generator on Dankclaw (user path https://notebook.franksdank.cloud; UI host
|
||||
# port **8502**, API host port **5056 loopback-only**). Read by
|
||||
# BOTH Quadlet units (dankclaw/open-notebook/quadlet/) as the FIRST
|
||||
# EnvironmentFile= line, which is why every path and host name below is the
|
||||
# value the CONTAINER must see.
|
||||
@@ -73,15 +74,20 @@ SURREAL_PASS=
|
||||
OPEN_NOTEBOOK_ENCRYPTION_KEY=
|
||||
OPEN_NOTEBOOK_PASSWORD=
|
||||
|
||||
# WHERE THE BROWSER FINDS THE API. The UI auto-detects `<host-you-opened>:5055`,
|
||||
# and 5055 on this host belongs to seerr, so the API leaves the container on 5056
|
||||
# and this line has to say so. Both origins are listed in CORS_ORIGINS because
|
||||
# the API is called cross-origin from the UI's own port: the LAN origin is the
|
||||
# normal one, the localhost one covers a browser opened on Dankclaw itself. The
|
||||
# app logs a warning at start while CORS_ORIGINS is unset and defaults to `*`,
|
||||
# which is a wildcard in front of an endpoint that serves every episode's audio.
|
||||
API_URL=http://192.168.0.143:5056
|
||||
CORS_ORIGINS=http://192.168.0.143:8502,http://localhost:8502
|
||||
# WHERE THE BROWSER FINDS THE API. The guarded vhost
|
||||
# (notebook.franksdank.cloud → Caddy → 8502) is the only user path, and the
|
||||
# image's own Next.js layer rewrites `/api/*` to the FastAPI running beside it,
|
||||
# so ONE origin serves UI and API and API_URL has to name that vhost. This is
|
||||
# not cosmetic: unset, the app auto-detects `<host-you-opened>:5055` — the port
|
||||
# upstream ships, and the one seerr holds on this host — and hands the browser
|
||||
# an address nothing answers; pointed at the LAN `:5056` instead, every call
|
||||
# leaves the guarded origin and an authenticated browser session does not ride
|
||||
# it. Same-origin traffic needs no CORS at all, but CORS_ORIGINS stays set to
|
||||
# the one origin because the app warns at start while it is unset and defaults
|
||||
# to `*` — a wildcard in front of an endpoint that serves every episode's
|
||||
# audio. No trailing slash: the UI concatenates `${API_URL}/api/...`.
|
||||
API_URL=https://notebook.franksdank.cloud
|
||||
CORS_ORIGINS=https://notebook.franksdank.cloud
|
||||
|
||||
# Concurrency: see "THE CPU-SHUTDOWN GUARD" above. Defaults are 5 and 5.
|
||||
TTS_BATCH_SIZE=1
|
||||
|
||||
Reference in New Issue
Block a user