feat(files): add Filestash player file share at files.${BASE_DOMAIN}
One shared login (htpasswd) for all players, writable. Config is rendered from a template and mounted read-only, so git stays authoritative — the admin console loads but cannot save, by design. Filestash's OIDC/SAML middlewares are enterprise-only, so Keycloak SSO is out; FILES_AUTH keeps htpasswd/passthrough switchable for later. Auth-off (passthrough) is only valid once the host is off the public internet — render-config.sh warns loudly when rendering it. Three traps, all found by testing against the pinned image: - the `local` backend is admin-gated: without LOCAL_BACKEND_SECRET in the connection params every login fails with "backend error - Not Allowed" - the htpasswd plugin only accepts $2a$ bcrypt, so a $2y$ hash from `htpasswd -B` fails every login silently — use `openssl passwd -6`. render-config.sh rejects the wrong format rather than shipping it - APPLICATION_URL/ADMIN_PASSWORD env make filestash rewrite config.json at boot, which fails on the :ro mount — both live in the rendered config Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
| `auth.${BASE_DOMAIN}` | `00-core.caddy` | `drasl:25585` |
|
||||
| `avatar.${BASE_DOMAIN}` | `40-avatar.caddy` | `nmsr:8080` |
|
||||
| `status.${BASE_DOMAIN}` | `50-status.caddy` | `uptime-kuma:3001` |
|
||||
| `files.${BASE_DOMAIN}` | `60-files.caddy` | `filestash:8334` |
|
||||
| `distribution.${BASE_DOMAIN}` | `30-distribution.caddy` | static `/srv/distribution` (other repo) |
|
||||
|
||||
---
|
||||
@@ -58,6 +59,29 @@ base `https://auth.${BASE_DOMAIN}/drasl/api/v2` (`site.draslApiUrl`):
|
||||
|
||||
---
|
||||
|
||||
## Files — `files.${BASE_DOMAIN}` (Filestash player share)
|
||||
|
||||
`reverse_proxy filestash:8334`. Screenshots / schematics / maps. **One shared
|
||||
login** for every player (`FILES_AUTH=htpasswd`), writable. Full design:
|
||||
`plan/20-files.md`.
|
||||
|
||||
- `/` — SPA. `GET /api/session/auth/?label=files` renders the login form;
|
||||
`POST` the same URL with `user`/`password` authenticates.
|
||||
- `/api/*` — JSON API. Requires the header `X-Requested-With: XmlHttpRequest`
|
||||
(the SPA sends it); without it Filestash's intrusion detection 403s the
|
||||
request. Relevant when curling it by hand.
|
||||
- `/admin` — admin console, own bcrypt password (`auth.admin`). Deliberately
|
||||
public; nginx throttles it (`limit_req`, 6r/m). It **cannot save** — the
|
||||
config is a read-only mount.
|
||||
- **`?label=files` matters.** The attribute mapping is keyed by the connection
|
||||
label; auth without it yields `backend error - Not Allowed`.
|
||||
|
||||
Filestash blocks any request whose `Host` doesn't match its `general.host`
|
||||
(`https://files.${BASE_DOMAIN}`) — nginx forwards the original Host and caddy
|
||||
passes it through, so don't rewrite it anywhere in the chain.
|
||||
|
||||
---
|
||||
|
||||
## Auth / Drasl — `auth.${BASE_DOMAIN}`
|
||||
|
||||
`reverse_proxy drasl:25585`. One service exposes three surfaces:
|
||||
|
||||
Reference in New Issue
Block a user