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:
@@ -159,6 +159,7 @@ services:
|
||||
- ./caddy/conf.d/30-distribution.caddy:/etc/caddy/conf.d/30-distribution.caddy:ro
|
||||
- ./caddy/conf.d/40-avatar.caddy:/etc/caddy/conf.d/40-avatar.caddy:ro
|
||||
- ./caddy/conf.d/50-status.caddy:/etc/caddy/conf.d/50-status.caddy:ro
|
||||
- ./caddy/conf.d/60-files.caddy:/etc/caddy/conf.d/60-files.caddy:ro
|
||||
- ./www:/srv/www:ro
|
||||
- ./launcher:/srv/launcher:ro
|
||||
# Static site from ANOTHER repo (absolute host path in .env).
|
||||
@@ -213,6 +214,38 @@ services:
|
||||
networks:
|
||||
- mcnet
|
||||
|
||||
# Player file share (screenshots, schematics, maps) at files.${BASE_DOMAIN}.
|
||||
# ONE shared login for everybody (FILES_AUTH=htpasswd), writable. See
|
||||
# plan/20-files.md — it documents every non-obvious bit of this service.
|
||||
#
|
||||
# Config is rendered read-only from filestash/config.json.tmpl: filestash has
|
||||
# no env-var config, and its admin console writes config.json back at runtime,
|
||||
# so pinning it :ro is what keeps git authoritative. The console still loads —
|
||||
# it just cannot save. That is intentional, not a bug.
|
||||
filestash:
|
||||
image: machines/filestash@sha256:8cb09d42470328a02aec6e3861f912addf8a9d54ad63d9c965bcb48df5ad36b1
|
||||
container_name: filestash
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
# The `local` storage backend is admin-gated in filestash: it refuses to
|
||||
# init unless the connection params carry this secret (or the admin
|
||||
# password). config.json's attribute_mapping supplies it server-side, so
|
||||
# players never see it. Without this, every login dies on "Not Allowed".
|
||||
LOCAL_BACKEND_SECRET: ${FILES_LOCAL_SECRET:?FILES_LOCAL_SECRET unset in .env}
|
||||
# Do NOT set APPLICATION_URL / ADMIN_PASSWORD here: either one makes
|
||||
# filestash rewrite config.json at boot, which fails on the :ro mount.
|
||||
# Both live in the rendered config instead (general.host / auth.admin).
|
||||
volumes:
|
||||
# /app/data/state holds config + sqlite + search index + logs, so the
|
||||
# DIRECTORY must stay writable. Only config.json is pinned read-only.
|
||||
- filestash_state:/app/data/state
|
||||
- ./filestash/config.json:/app/data/state/config/config.json:ro
|
||||
# The share itself. FILES_MOUNT_MODE is the literal mount flag (ro|rw) —
|
||||
# `ro` enforces a read-only share at the KERNEL, whatever the UI thinks.
|
||||
- ${FILES_DATA_DIR:?FILES_DATA_DIR unset in .env}:/data/files:${FILES_MOUNT_MODE:-ro}
|
||||
networks:
|
||||
- mcnet
|
||||
|
||||
# Status monitoring + public status page. caddy proxies status. -> :3001.
|
||||
# Joins mcnet so monitors probe the stack by internal service name.
|
||||
uptime-kuma:
|
||||
@@ -228,6 +261,7 @@ volumes:
|
||||
drasl_state:
|
||||
mc_data:
|
||||
kuma_data:
|
||||
filestash_state:
|
||||
|
||||
networks:
|
||||
mcnet:
|
||||
|
||||
Reference in New Issue
Block a user