diff --git a/next.config.mjs b/next.config.mjs index 02a1df3..a53a603 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,4 +1,6 @@ import { withPayload } from "@payloadcms/next/withPayload"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; import packageJson from "./package.json" with { type: "json" }; @@ -8,6 +10,13 @@ const nextConfig = { env: { version: packageJson.version, }, + // Pin the workspace root to this repo dir so the standalone build emits a + // flat .next/standalone/server.js (Next otherwise walks up looking for + // lockfiles and can pick a parent directory — here a stray + // /home/jason/package-lock.json two levels up would nest the standalone + // tree under .next/standalone/WebstormProjects/polaris-task-force/, which + // breaks the Dockerfile's `COPY .../standalone ./` + `CMD ["node","server.js"]`). + outputFileTracingRoot: path.resolve(path.dirname(fileURLToPath(import.meta.url))), webpack: (webpackConfig) => { webpackConfig.resolve.extensionAlias = { ".cjs": [".cts", ".cjs"], diff --git a/src/app/(frontend)/layout.tsx b/src/app/(frontend)/layout.tsx index 74366b6..67c23d0 100644 --- a/src/app/(frontend)/layout.tsx +++ b/src/app/(frontend)/layout.tsx @@ -15,6 +15,14 @@ import { GameTickRealtime } from "@/components/frontend/realtime/GameTickRealtim import { LandingPage } from "@/components/frontend/LandingPage"; import { Toaster } from "@/components/ui/sonner"; +// Skip static prerendering of this layout (and all pages under (frontend)/). +// The layout calls `getPayload()` at render time to resolve the current user, +// which connects to PostgreSQL. With force-dynamic, Next.js skips the +// build-time prerender pass (which would try to init Payload and hit the DB) +// and instead server-renders at request time. Without this, `next build` +// inside a container with no reachable DATABASE_URI fails. +export const dynamic = "force-dynamic"; + export const metadata: Metadata = { description: "A gamified platform for Polaris Task Force, an Arma 3 unit.", title: "Polaris Task Force", diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index 4199098..3d3a018 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -2,8 +2,13 @@ import { getPayload } from "payload"; import config from "@payload-config"; import { headers as nextHeaders } from "next/headers"; import { redirect } from "next/navigation"; -import { ShieldIcon } from "lucide-react"; import { LoginForm } from "@/components/frontend/auth/LoginForm"; +import AppLogo from "@/components/graphics/AppLogo"; + +// See (frontend)/layout.tsx for rationale. The login page also calls +// getPayload() at render time and must not be prerendered during `next build` +// (no DB is available at build time in a container). +export const dynamic = "force-dynamic"; export default async function LoginPage() { const payload = await getPayload({ config }); @@ -15,10 +20,9 @@ export default async function LoginPage() { return (
-
- +
+
-

Polaris Task Force

Log in to access the operations dashboard, intelligence, and logistics.