somratpro Claude Opus 4.7 commited on
Commit
12bbc56
ยท
1 Parent(s): 2ecb798

fix: serve Next.js public/ files from disk to avoid nginx basePath 502s

Browse files

Requests for static assets like /app/auth/avatars/*.jpg reach nginx as
/auth/avatars/*.jpg; our nginx patch re-adds /app/ making it
/app/auth/avatars/*.jpg for Next.js:4200. Next.js can't serve public/
files at that prefixed path โ†’ nginx returns 502.

health-server now intercepts /app/<ext> paths that are not /_next/ assets
and streams them directly from /app/apps/frontend/public/. Falls back to
the nginx proxy if the file isn't found there.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

Files changed (1) hide show
  1. health-server.js +41 -1
health-server.js CHANGED
@@ -22,8 +22,22 @@ const http = require("http");
22
  const https = require("https");
23
  const fs = require("fs");
24
  const net = require("net");
 
25
 
26
  const PORT = 7860;
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  const POSTIZ_HOST = "127.0.0.1";
28
  const POSTIZ_PORT = 5000;
29
 
@@ -840,10 +854,36 @@ const server = http.createServer((req, res) => {
840
  return;
841
  }
842
 
843
- // โ”€โ”€ /app/* โ†’ strip prefix, proxy to Postiz nginx :5000 โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
844
  if (pathname.startsWith("/app/")) {
845
  const stripped = pathname.slice("/app".length) || "/";
846
  const query = parsedUrl.search || "";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
847
  proxyHttp(req, res, stripped + query);
848
  return;
849
  }
 
22
  const https = require("https");
23
  const fs = require("fs");
24
  const net = require("net");
25
+ const path = require("path");
26
 
27
  const PORT = 7860;
28
+
29
+ // Static files in Next.js public/ directory are served directly from disk.
30
+ // The nginx proxy chain re-adds the /app basePath prefix when forwarding to
31
+ // Next.js:4200, making public file paths misalign. Serving from disk here
32
+ // is simpler and faster.
33
+ const NEXTJS_PUBLIC_DIR = "/app/apps/frontend/public";
34
+ const MIME_TYPES = {
35
+ ".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".png": "image/png",
36
+ ".gif": "image/gif", ".webp": "image/webp", ".svg": "image/svg+xml",
37
+ ".ico": "image/x-icon", ".woff": "font/woff", ".woff2": "font/woff2",
38
+ ".ttf": "font/ttf", ".eot": "application/vnd.ms-fontobject",
39
+ ".txt": "text/plain; charset=utf-8", ".xml": "application/xml",
40
+ };
41
  const POSTIZ_HOST = "127.0.0.1";
42
  const POSTIZ_PORT = 5000;
43
 
 
854
  return;
855
  }
856
 
857
+ // โ”€โ”€ /app/* โ†’ serve public static files from disk, proxy the rest โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
858
  if (pathname.startsWith("/app/")) {
859
  const stripped = pathname.slice("/app".length) || "/";
860
  const query = parsedUrl.search || "";
861
+
862
+ // Static files in Next.js public/ land here with /app/ prefix (basePath).
863
+ // Serve them directly from disk instead of proxying through nginx so the
864
+ // path mismatch introduced by the nginx /app/ re-add patch doesn't matter.
865
+ // _next/ bundles are NOT in public/ โ€” skip them and proxy normally.
866
+ const ext = path.extname(stripped).toLowerCase();
867
+ if (ext && !stripped.startsWith("/_next/") && MIME_TYPES[ext]) {
868
+ const absPath = path.resolve(NEXTJS_PUBLIC_DIR, "." + stripped);
869
+ if (absPath.startsWith(NEXTJS_PUBLIC_DIR + path.sep)) {
870
+ const stream = fs.createReadStream(absPath);
871
+ stream.once("open", () => {
872
+ res.writeHead(200, {
873
+ "Content-Type": MIME_TYPES[ext],
874
+ "Cache-Control": "public, max-age=86400",
875
+ });
876
+ stream.pipe(res);
877
+ });
878
+ stream.once("error", () => {
879
+ // File not in public/ โ€” fall through to nginx proxy.
880
+ if (!res.headersSent) proxyHttp(req, res, stripped + query);
881
+ else res.destroy();
882
+ });
883
+ return;
884
+ }
885
+ }
886
+
887
  proxyHttp(req, res, stripped + query);
888
  return;
889
  }