fix: resolve Next.js docker build endpoints and handle async map icons

Former-commit-id: 6241ea44db
This commit is contained in:
anoracleofra-code
2026-03-09 00:37:08 -06:00
parent 197d37ae5a
commit 19a0ef1c70
5 changed files with 59 additions and 5 deletions
-1
View File
@@ -1 +0,0 @@
f5eaed9b0fba2bd73f0597d9659b616cae4291b5
+4 -2
View File
@@ -19,11 +19,13 @@ services:
frontend:
build:
context: ./frontend
args:
# Optional: set this to your backend's external URL if using custom ports
# e.g. http://192.168.1.50:9096 — leave empty to auto-detect from browser
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-}
container_name: shadowbroker-frontend
ports:
- "3000:3000"
environment:
- NEXT_PUBLIC_API_URL=http://localhost:8000
depends_on:
- backend
restart: unless-stopped
+4
View File
@@ -11,6 +11,10 @@ WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ENV NEXT_TELEMETRY_DISABLED 1
# NEXT_PUBLIC_* vars must exist at build time for Next.js to inline them.
# Default empty = auto-detect from browser hostname at runtime.
ARG NEXT_PUBLIC_API_URL=""
ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL
RUN npm run build
FROM base AS runner
+23 -1
View File
@@ -373,15 +373,37 @@ const MaplibreViewer = ({ data, activeLayers, onEntityClick, flyToLocation, sele
const onMapLoad = useCallback((e: any) => {
const map = e.target;
// Track which images are still loading so we can retry on styleimagemissing
const pendingImages: Record<string, string> = {};
const loadImg = (id: string, url: string) => {
if (!map.hasImage(id)) {
pendingImages[id] = url;
const img = new Image();
img.crossOrigin = "anonymous";
img.src = url;
img.onload = () => map.addImage(id, img);
img.onload = () => {
if (!map.hasImage(id)) map.addImage(id, img);
delete pendingImages[id];
};
}
};
// Suppress "image not found" warnings — retry when the async load finishes
map.on('styleimagemissing', (ev: any) => {
const id = ev.id;
const url = pendingImages[id];
if (url) {
const img = new Image();
img.crossOrigin = "anonymous";
img.src = url;
img.onload = () => {
if (!map.hasImage(id)) map.addImage(id, img);
delete pendingImages[id];
};
}
});
// Legacy generic plane icons (still used as fallbacks)
loadImg('svgPlaneCyan', svgPlaneCyan);
loadImg('svgPlaneYellow', svgPlaneYellow);
+28 -1
View File
@@ -1 +1,28 @@
export const API_BASE = process.env.NEXT_PUBLIC_API_URL || "http://localhost:8000";
// NEXT_PUBLIC_* vars are baked at build time in Next.js, so setting them
// in docker-compose `environment` has no effect at runtime. Instead we
// auto-detect: use the browser's current hostname with a configurable port
// so the dashboard works on localhost, LAN IPs, and custom Docker port maps
// without any code changes.
//
// Override order:
// 1. Build-time NEXT_PUBLIC_API_URL (for advanced users who rebuild the image)
// 2. Runtime auto-detect from window.location.hostname + port 8000
function resolveApiBase(): string {
// Build-time override (works when image is rebuilt with the env var)
if (process.env.NEXT_PUBLIC_API_URL) {
return process.env.NEXT_PUBLIC_API_URL;
}
// Server-side rendering: fall back to localhost
if (typeof window === "undefined") {
return "http://localhost:8000";
}
// Client-side: use the same hostname the user is browsing on
const proto = window.location.protocol;
const host = window.location.hostname;
return `${proto}//${host}:8000`;
}
export const API_BASE = resolveApiBase();