mirror of
https://github.com/BigBodyCobain/Shadowbroker.git
synced 2026-08-19 08:57:20 +02:00
Stabilize Docker startup and runtime proxy
Reduce cold-start stalls by raising the default backend memory limit, bounding heavy feed concurrency, preserving non-empty startup caches, and refreshing working news feeds. Fix the Next API proxy for Docker control-plane writes by stripping unsupported hop/body headers and forwarding small request bodies safely. Keep the dashboard dynamic so production users do not get stuck on a cached startup shell.
This commit is contained in:
@@ -26,6 +26,8 @@ const STRIP_REQUEST = new Set([
|
||||
'transfer-encoding',
|
||||
'upgrade',
|
||||
'host',
|
||||
'content-length',
|
||||
'expect',
|
||||
]);
|
||||
|
||||
// Headers that must not be forwarded back to the browser.
|
||||
@@ -201,9 +203,10 @@ async function proxy(req: NextRequest, pathSegments: string[]): Promise<NextResp
|
||||
cache: 'no-store',
|
||||
};
|
||||
if (!isBodyless) {
|
||||
requestInit.body = req.body;
|
||||
// Required for streaming request bodies in Node.js fetch
|
||||
requestInit.duplex = 'half';
|
||||
const body = await req.text();
|
||||
if (body.length > 0) {
|
||||
requestInit.body = body;
|
||||
}
|
||||
}
|
||||
const maxAttempts = isBodyless ? 18 : 1;
|
||||
let fetchError: unknown = null;
|
||||
@@ -214,6 +217,13 @@ async function proxy(req: NextRequest, pathSegments: string[]): Promise<NextResp
|
||||
break;
|
||||
} catch (error) {
|
||||
fetchError = error;
|
||||
if (attempt >= maxAttempts) {
|
||||
console.error('api proxy upstream fetch failed', {
|
||||
method: req.method,
|
||||
target: targetUrl.toString(),
|
||||
error,
|
||||
});
|
||||
}
|
||||
if (attempt >= maxAttempts) break;
|
||||
await sleep(250);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,12 @@ export const metadata: Metadata = {
|
||||
description: 'Advanced Geopolitical Risk Dashboard',
|
||||
};
|
||||
|
||||
// The dashboard is a live local runtime, not a static landing page. If Next
|
||||
// prerenders and caches the initial shell, Docker users can get stuck on the
|
||||
// "prioritizing map feeds" markup before client polling ever hydrates.
|
||||
export const dynamic = 'force-dynamic';
|
||||
export const revalidate = 0;
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
|
||||
@@ -13,8 +13,8 @@ function buildCsp(nonce: string): string {
|
||||
const directives = [
|
||||
"default-src 'self'",
|
||||
isDev
|
||||
? `script-src 'self' 'unsafe-inline' 'unsafe-eval' 'nonce-${nonce}' blob:`
|
||||
: `script-src 'self' 'unsafe-inline' 'nonce-${nonce}' blob:`,
|
||||
? "script-src 'self' 'unsafe-inline' 'unsafe-eval' blob:"
|
||||
: "script-src 'self' 'unsafe-inline' blob:",
|
||||
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com",
|
||||
"img-src 'self' data: blob: https:",
|
||||
isDev
|
||||
@@ -35,7 +35,10 @@ function buildCsp(nonce: string): string {
|
||||
export function middleware(request: NextRequest) {
|
||||
const nonce = Buffer.from(crypto.randomUUID()).toString('base64');
|
||||
|
||||
// Forward nonce to server components via request header.
|
||||
// Forward a nonce for future fully-wired CSP support. Do not include it in
|
||||
// script-src until every Next inline bootstrap script receives the nonce;
|
||||
// otherwise production hydration can fail and leave the app on the static
|
||||
// "prioritizing map feeds" shell.
|
||||
const requestHeaders = new Headers(request.headers);
|
||||
requestHeaders.set('x-nonce', nonce);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user