fix(deploy): writable data_dir in container + fatal-on-mkdir

The Dockerfile created the minstrel user but never set a WORKDIR or
pre-created a writable data dir. With the default DataDir of "./data"
and CWD of "/", every MkdirAll attempt failed with "permission denied"
under the non-root user, and the boot code only logged a Warn before
continuing. Result: every artist-art enrichment failed at
"mkdir artist-art: mkdir data: permission denied"; the operator saw
"0 successes" with no signal as to why.

Three changes:
- Dockerfile: WORKDIR /app, pre-create /app/data with minstrel
  ownership, and ENV MINSTREL_STORAGE_DATA_DIR=/app/data so the
  binary doesn't fall back to the broken "./data" default even if
  the operator forgets to set it.
- docker-compose.yml: explicit MINSTREL_STORAGE_DATA_DIR + a named
  volume mounted at /app/data so cached art persists across
  container recreates.
- cmd/minstrel/main.go: MkdirAll failure is now fatal. Silent breakage
  here cascades into every cache (playlist covers, artist art,
  album-cover fallbacks); refusing to start surfaces the misconfig
  immediately. Also wires Enricher.DataDir from cfg in preparation
  for the album-cover sidecar fallback (next commit).
This commit is contained in:
2026-05-06 23:28:54 -04:00
parent 876f994904
commit 5207fae653
3 changed files with 21 additions and 3 deletions
+6 -3
View File
@@ -91,6 +91,7 @@ func run() error {
os.Exit(1)
}
coverEnricher := coverart.NewEnricher(pool, logger.With("component", "coverart"), coverSettings)
coverEnricher.DataDir = cfg.Storage.DataDir
// One unified scan chain: library walk → MBID backfill → cover enrich.
// Boot-time scan and manual-trigger scans share this path; results land
@@ -148,12 +149,14 @@ func run() error {
go lidarrReconciler.Run(ctx)
// Ensure DataDir exists before any service tries to write into it.
// Best-effort: log + continue on failure; the playlist cover writer
// will surface a clearer error at first use.
// Fatal on failure: a non-writable data_dir silently breaks every
// downstream cache (playlist covers, artist art, album-cover fallback)
// and produces "0 successes" symptoms that are hard to diagnose.
if cfg.Storage.DataDir != "" {
if err := os.MkdirAll(cfg.Storage.DataDir, 0o755); err != nil {
logger.Warn("data_dir create failed; cached artifacts may not persist",
logger.Error("data_dir create failed; refusing to start",
"path", cfg.Storage.DataDir, "err", err)
os.Exit(1)
}
}