From 7f774e95bb91f39d414d2bba06d820c749479c56 Mon Sep 17 00:00:00 2001 From: Stefan Lazic Date: Fri, 4 Sep 2026 21:22:33 +0100 Subject: [PATCH] Build failure fix --- Dockerfile | 12 ++++++------ src/lib/media/media-storage.ts | 2 +- src/services/management/provisioning.service.ts | 15 ++++++++++++--- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index 14a3261..52f9556 100644 --- a/Dockerfile +++ b/Dockerfile @@ -38,12 +38,12 @@ COPY . . # satisfy that check; the real values are supplied at container runtime # via env_file (see docker-compose.local.yaml) and these are never used to # connect to anything or baked into a layer that matters. -ENV DATABASE_HOST="localhost" -ENV DATABASE_PORT="3306" -ENV DATABASE_NAME="build" -ENV DATABASE_USER="build" -ENV DATABASE_PASSWORD="build" -RUN npm run build +RUN DATABASE_HOST="localhost" \ + DATABASE_PORT="3306" \ + DATABASE_NAME="build" \ + DATABASE_USER="build" \ + DATABASE_PASSWORD="build" \ + npm run build FROM node:22-alpine AS runner WORKDIR /app diff --git a/src/lib/media/media-storage.ts b/src/lib/media/media-storage.ts index c7ccbe2..6e3255b 100644 --- a/src/lib/media/media-storage.ts +++ b/src/lib/media/media-storage.ts @@ -44,7 +44,7 @@ const EXTENSION_MIME_TYPES: Record = { export const MEDIA_MAX_UPLOAD_BYTES = Number(process.env.MEDIA_MAX_UPLOAD_BYTES ?? 5_000_000); /** Overridable so a non-Docker deployment can point this somewhere else; defaults to a directory next to the app, outside public/. */ -const MEDIA_ROOT = path.resolve(process.env.MEDIA_STORAGE_ROOT || path.join(process.cwd(), "storage", "media")); +const MEDIA_ROOT = path.resolve(process.env.MEDIA_STORAGE_ROOT || path.join(/* turbopackIgnore: true */ process.cwd(), "storage", "media")); export const MEDIA_URL_PREFIX = "/api/media/"; diff --git a/src/services/management/provisioning.service.ts b/src/services/management/provisioning.service.ts index 3f8db2c..8de7dd0 100644 --- a/src/services/management/provisioning.service.ts +++ b/src/services/management/provisioning.service.ts @@ -15,6 +15,10 @@ function containerName(slug: string) { return `nextchair-${slug}`; } +function healthState(value: string | undefined): BusinessStatus["health"] { + return value === "healthy" || value === "unhealthy" || value === "starting" ? value : "unknown"; +} + async function readRegistry(): Promise { try { return JSON.parse(await fs.readFile(registryPath(), "utf8")) as BusinessDeployment[]; @@ -36,7 +40,7 @@ async function inspectContainer(slug: string) { try { const result = await docker(["inspect", "-f", "{{.State.Status}}|{{if .State.Health}}{{.State.Health.Status}}{{end}}", containerName(slug)]); const [container, health] = result.stdout.trim().split("|"); - return { container: container === "running" ? "running" : container ? "stopped" : "unknown", health: health || "unknown" } as const; + return { container: container === "running" ? "running" : container ? "stopped" : "unknown", health: healthState(health) } as const; } catch { return { container: "unknown", health: "unknown" } as const; } @@ -54,8 +58,13 @@ async function databaseStatus() { async function storageBytes(slug: string) { try { const volume = await docker(["volume", "inspect", "-f", "{{.Mountpoint}}", `nextchair-media-${slug}`]); - const usage = await run("du", ["-sk", volume.stdout.trim()], { maxBuffer: 1024 * 64 }); - return Number.parseInt(usage.stdout.trim().split(/\s+/)[0], 10) * 1024; + const mountpoint = volume.stdout.trim(); + if (!mountpoint) return null; + const usage = await run("du", ["-sk", mountpoint], { maxBuffer: 1024 * 64 }); + const kilobytes = usage.stdout.trim().split(/\s+/)[0]; + if (!kilobytes) return null; + const bytes = Number.parseInt(kilobytes, 10) * 1024; + return Number.isFinite(bytes) ? bytes : null; } catch { return null; }