Files
cms/apps/hanzo-demo/next.config.ts
zeekayandHanzo Dev a5d5c2b8c6 build(cms): stand up the canonical image pipeline (Dockerfile + hanzo.yml + cicd.yml)
cms.hanzo.ai's image (cms:3.85.9) was built OUT-OF-BAND — no Dockerfile, no
hanzo.yml, zero GH Actions image runs ever. This commits the missing pipeline so
a rebranded image builds from a repeatable trigger instead of a dev box:

- apps/hanzo-demo/next.config.ts: output:'standalone' + outputFileTracingRoot at
  the workspace root, so the build emits .next/standalone/apps/hanzo-demo/server.js
  — exactly what the operator CR runs (node apps/hanzo-demo/server.js).
- Dockerfile: multi-stage, pnpm 10.27 (corepack), pnpm build:all + the app's
  next build --webpack, slim runner copying the standalone tree.
- hanzo.yml + .github/workflows/cicd.yml: the canonical hanzoai/ci path (mirrors
  hanzoai/world) — push to main builds ghcr.io/hanzoai/cms + rolls the cms CR;
  KMS supplies the GHCR token + kubeconfig. main.yml (upstream tests) untouched.

FIRST-CUT — needs a CI build to validate (a Payload monorepo standalone image is
finicky; I did NOT build it on the box per the CI/CD-only rule). If the existing
3.85.9 Dockerfile is available, it should supersede this.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-12 22:08:04 -07:00

55 lines
2.1 KiB
TypeScript

import type { NextConfig } from 'next'
import { withCMS } from '@hanzo/cms-next/withPayload'
import path from 'path'
import { fileURLToPath } from 'url'
const __filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(__filename)
const nextConfig: NextConfig = {
// Emit a self-contained server bundle so the image can run `node
// apps/hanzo-demo/server.js` (exactly what the operator CR invokes) without
// node_modules. In a pnpm monorepo the standalone lands at
// .next/standalone/apps/hanzo-demo/server.js, so file-tracing must root at the
// workspace, not the app dir, or the traced runtime misses workspace deps.
images: {
localPatterns: [
{
pathname: '/api/media/file/**',
},
],
},
output: 'standalone',
outputFileTracingRoot: path.resolve(dirname, '../..'),
turbopack: {
// Monorepo root (two levels up from apps/hanzo-demo). In this pnpm
// isolated-linker workspace `next` is symlinked from the root .pnpm store,
// so its realpath lives at <root>/node_modules/.pnpm/... — outside the app
// dir. Turbopack refuses to resolve packages outside its root, so the root
// MUST be the monorepo root or `next build` fails with "couldn't find the
// Next.js package (next/package.json)".
root: path.resolve(dirname, '../..'),
},
typescript: {
// Matches the monorepo root next.config.mjs. In-workspace the @hanzo/cms*
// packages resolve to their raw TS `src/` (via `exports`), so a `next build`
// type-check would re-check the ENTIRE Payload source tree — unbounded and
// redundant: every package already validates its own types via `build:types`
// (tsc --emitDeclarationOnly) during `turbo build`. The app's own types are
// checked there too. Leaving this on OOMs / runs for many minutes.
ignoreBuildErrors: true,
},
webpack: (webpackConfig) => {
webpackConfig.resolve.extensionAlias = {
'.cjs': ['.cts', '.cjs'],
'.js': ['.ts', '.tsx', '.js', '.jsx'],
'.mjs': ['.mts', '.mjs'],
}
return webpackConfig
},
}
export default withCMS(nextConfig, { devBundleServerPackages: false })