mymusics

retro MySpace-style music player
Log | Files | Refs | README

commit 7e447423cbf0993a392ea953b9af969093c70ba0
parent f8de9eecef000aee0c6411b8c43a6d22602610a0
Author: Pablo Murad <pblmrd@gmail.com>
Date:   Fri,  1 May 2026 11:59:37 -0300

favicon

Diffstat:
MREADME.md | 2+-
Mserver/index.ts | 49+++++++++++++++++++++++++++++++++++--------------
2 files changed, 36 insertions(+), 15 deletions(-)

diff --git a/README.md b/README.md @@ -14,7 +14,7 @@ Retro-styled web player that picks random tracks from [`metadata.tsv`](../data/m - `METADATA_TSV` — path to `metadata.tsv` (default: `../data/metadata.tsv` relative to this folder). - **Ports** — defined in [`config/ports.ts`](config/ports.ts) as paired pools. Use `PORT_INDEX` (0–3) to pick a pair, or set `PORT` / `VITE_DEV_PORT` explicitly. Defaults: API `38471`, Vite dev `38472` (index 0). - `IA_ITEM_ID` (optional) — Internet Archive item id (default `myspace_dragon_hoard_2010`). - - `SERVE_STATIC` — set to `true` in production so Fastify serves `dist/` and `/api` on one port (required for PM2 single-process deploy). + - `SERVE_STATIC` — if `dist/index.html` exists after `npm run build`, the app serves the SPA + `/api` automatically. Set `SERVE_STATIC=false` for API-only. Explicit `true`/`1` is optional; use it when you want a clear flag in PM2/systemd. 2. Install dependencies: diff --git a/server/index.ts b/server/index.ts @@ -29,8 +29,15 @@ const METADATA_TSV = process.env.METADATA_TSV const IA_ITEM_ID = process.env.IA_ITEM_ID?.trim() || IA_DRAGON_HOARD_ID; const distDir = path.join(__dirname, "..", "dist"); -const serveStatic = +const distIndexPath = path.join(distDir, "index.html"); +const distExists = fs.existsSync(distIndexPath); + +/** Serve Vite build from dist/ when it exists (typical behind nginx). Opt out with SERVE_STATIC=false. */ +const staticDisabled = + process.env.SERVE_STATIC === "false" || process.env.SERVE_STATIC === "0"; +const staticExplicit = process.env.SERVE_STATIC === "true" || process.env.SERVE_STATIC === "1"; +const serveStatic = !staticDisabled && (staticExplicit || distExists); let pool: TrackMeta[] = []; @@ -92,19 +99,33 @@ async function main() { }); }); - if (serveStatic && fs.existsSync(path.join(distDir, "index.html"))) { - await app.register(fastifyStatic, { - root: distDir, - prefix: "/", - }); - app.setNotFoundHandler((request, reply) => { - const pathname = request.url.split("?")[0] ?? ""; - if (pathname.startsWith("/api")) { - return reply.code(404).send({ error: "Not found" }); - } - return reply.sendFile("index.html"); - }); - console.info(`MyMusics: serving static files from ${distDir}`); + if (serveStatic) { + if (distExists) { + await app.register(fastifyStatic, { + root: distDir, + prefix: "/", + }); + app.setNotFoundHandler((request, reply) => { + const pathname = request.url.split("?")[0] ?? ""; + if (pathname.startsWith("/api")) { + return reply.code(404).send({ error: "Not found" }); + } + return reply.sendFile("index.html"); + }); + console.info(`MyMusics: serving SPA + /api from ${distDir}`); + } else { + console.warn( + "MyMusics: SERVE_STATIC requested but dist/index.html is missing — run `npm run build` on the server.", + ); + } + } else if (distExists) { + console.info( + "MyMusics: dist/ exists but SPA is disabled (SERVE_STATIC=false); GET / returns 404, /api only.", + ); + } else { + console.info( + "MyMusics: API only (no dist/). Use `npm run build` or set up Vite dev; nginx should not proxy / to this port until SPA is served.", + ); } await app.listen({ port: PORT, host: "0.0.0.0" });