BUG: Frontend dashboard not served — missing express.static middleware (regression in v1.7.26) #57
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
The sofarr server starts successfully and the backend API works perfectly, but the frontend dashboard UI is never served.
Visiting the root URL (
/) or any non-API path returns a 404/500 instead of the expected Vite-built SPA (public/index.html). Thepublic/directory (containingindex.html,app.js,style.css, etc.) and the entireclient/Vite frontend source exist in the repository but are completely ignored by the Express application.This explains the reported symptom: "the app is no longer accepting web connections for the front end despite running".
Steps to Reproduce
mainbranch.docker compose up) ornpm start.http://localhost:3001(or your configuredPORT/ domain).curl http://localhost:3001/health→{"status":"ok"}Expected Behavior
public/at the root path.GET /→ servespublic/index.html(the dashboard).index.html.Actual Behavior
server/app.jsorserver/index.js./api/*,/health,/ready,/api/swagger*) fall through to the global error handler.public/are present but never mounted.Root Cause Analysis
File:
server/app.js(thecreateApp()factory function)After mounting all API routes, rate limiters, CSRF protection, Helmet CSP, Swagger UI, etc., there is zero code that serves the frontend:
File:
server/index.jslisten(PORT)correctly binds to all interfaces (0.0.0.0).appit serves has no frontend routes.Evidence of intended frontend:
public/index.html,public/app.js,public/style.cssexist.client/contains a full Vite +src/SPA project (vite.config.js,package.json).This appears to be a regression — the static serving middleware was likely removed or never properly re-added when the app was refactored into the current
createApp()+ separateindex.jsstructure.Additional Context / Contributing Factors
TLS_ENABLED=true) uses self-signed snakeoil certs → browsers will also block the UI even if static serving were present.'self', but irrelevant without a frontend origin.express.staticor SPA fallback (app.get('*', ...)) exists anywhere in the codebase.public/folder is included in the Docker image (via.dockerignorerules) but remains unused.Suggested Fix
Add the following in
server/app.jsinsidecreateApp(), after all API routes but before the error handler:Also consider:
client/is built intopublic/.index.jsto mention the frontend is being served.Impact
Resolved in commit
86277e2.