fix(storage): serve assets via app routes when MEDIA_PUBLIC_BASE_URL is unset

publicUrl() defaulted MEDIA_BASE to "/media" even with no env set, so cover
art on public share pages pointed at a /media path that only the old nginx
(Plesk) box served. In the containerized Coolify/Docker deploy nothing serves
/media, breaking those images. Return null when MEDIA_PUBLIC_BASE_URL is unset
so callers fall back to the app's own /api/public/.../cover route (the deploy
README already documents assets as app-served). Backward compatible: behavior
is unchanged when the env var is set.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Leon Serfaty
2026-06-20 21:10:52 -04:00
parent 51c541ad22
commit 19a403b431
+6 -2
View File
@@ -3,7 +3,11 @@ import path from "node:path";
import type { StorageProvider } from "./types"; import type { StorageProvider } from "./types";
const STORAGE_DIR = path.resolve(process.env.STORAGE_DIR ?? "./storage"); const STORAGE_DIR = path.resolve(process.env.STORAGE_DIR ?? "./storage");
const MEDIA_BASE = process.env.MEDIA_PUBLIC_BASE_URL ?? "/media"; // Only when an external static server (e.g. nginx on the Plesk box) serves the
// art directory is MEDIA_PUBLIC_BASE_URL set. In the containerized deploy it is
// unset and the app serves assets itself via /api routes — so publicUrl() must
// return null then, letting callers fall back instead of pointing at a dead /media.
const MEDIA_BASE = process.env.MEDIA_PUBLIC_BASE_URL?.trim() || null;
// Cover art is the only asset class served publicly by nginx from /media. // Cover art is the only asset class served publicly by nginx from /media.
const PUBLIC_PREFIXES = ["art/"]; const PUBLIC_PREFIXES = ["art/"];
@@ -67,7 +71,7 @@ export class LocalStorageProvider implements StorageProvider {
} }
publicUrl(key: string): string | null { publicUrl(key: string): string | null {
if (PUBLIC_PREFIXES.some((p) => key.startsWith(p))) { if (MEDIA_BASE && PUBLIC_PREFIXES.some((p) => key.startsWith(p))) {
return `${MEDIA_BASE}/${key}`; return `${MEDIA_BASE}/${key}`;
} }
return null; return null;