Next.js Runtime Deployment (F2.1)
Feature: F2.1 — Next.js Deployment
Status: Completed
Package: System Layer (build_manager.py,docker_manager.py,next.yml), Fastify API (modules/build)
1. Overview
Vexlyx provides zero-config, native runtime deployment for Next.js applications. It supports modern Next.js features including:
- Server-Side Rendering (SSR) & React Server Components (RSC)
- API Routes & Route Handlers (
/api/...,app/api/...) - Static Site Generation (SSG) & Incremental Static Regeneration (ISR)
- Next.js Image Optimization (
next/image) - Build Caching: Preserves
.next/cache,node_modules/.cache, and package manager cache for fast redeployments - Dual-Phase Environment Variable Injection: Inlines
NEXT_PUBLIC_*variables at build time and injects all encrypted variables at runtime in Docker containers.
2. Architecture & Execution Flow
┌─────────────────────────┐
│ Git Connect / Workspace │
└────────────┬────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Framework Detection Heuristics (`build_manager.py plan`)│
│ - next.config.js / mjs / ts / cjs │
│ - package.json -> dependencies.next │
│ - lockfile detection (npm, pnpm, yarn, bun) │
└────────────┬────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Build Phase (`nixpacks build`) │
│ - Build command: `npm run build` / lockfile override │
│ - Build cache key: `vexlyx-<projectId>` │
│ - Build-time env vars: `--env NEXT_PUBLIC_*=...` │
└────────────┬────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Deploy Phase (`docker_manager.py deploy`) │
│ - Template: `system/templates/docker-compose/next.yml` │
│ - HOST=0.0.0.0, HOSTNAME=0.0.0.0, PORT=3000 │
│ - NEXT_TELEMETRY_DISABLED=1 │
│ - Traefik dynamic router & load balancer │
└─────────────────────────────────────────────────────────┘3. Auto-Detection Heuristics
When nixpacks plan runs on a project repository, Vexlyx inspects the workspace for Next.js indicators:
- Config File Presence:
next.config.jsnext.config.mjsnext.config.tsnext.config.cjs
- Package Dependency:
package.jsonwith"next"listed underdependenciesordevDependencies
- Lockfile & Command Resolution:
pnpm-lock.yaml→pnpm run build/pnpm run startyarn.lock→yarn build/yarn startbun.lockborbun.lock→bun run build/bun run startpackage-lock.json/ default →npm run build/npm run start
When detected:
- Framework is identified as
nextjs(displayed asNext.js). - Database
project.typeis automatically aligned toNEXTJS. - Build logs record:
[vexlyx] Detected framework: Next.js.
4. Build Caching & Environment Variables
Build Caching
Nixpacks is executed with:
nixpacks build <projectDir> --name <imageName> --cache-key vexlyx-<projectId>This ensures .next/cache and node_modules/.cache are preserved across redeployments, cutting build times by 50-80% on subsequent commits.
Environment Variable Injection
Next.js distinguishes between client-side build-time variables and runtime server-side variables:
- Build Time: All decrypted project environment variables (especially
NEXT_PUBLIC_*) are passed via--env KEY=VALUEtonixpacks build. - Runtime: All environment variables are injected into the container via the generated
docker-compose.ymlenvironment:block.
5. Container & Compose Template (next.yml)
Next.js 13+ servers bind to localhost by default unless HOSTNAME=0.0.0.0 or HOST=0.0.0.0 is provided. The next.yml template ensures proper container network bridging:
services:
app:
image: "{{image_name}}"
restart: unless-stopped
environment:
PORT: "{{container_port}}"
HOST: "0.0.0.0"
HOSTNAME: "0.0.0.0"
NODE_ENV: production
NEXT_TELEMETRY_DISABLED: "1"
{{env_block}}
ports:
- "{{host_port}}:{{container_port}}"
deploy:
resources:
limits:
memory: "{{memory_limit}}"
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://localhost:{{container_port}}/ || wget -qO- http://localhost:{{container_port}}/api/health || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
labels:
- "traefik.enable=true"
- "traefik.http.routers.{{service_name}}.rule=Host(`{{hostname}}`)"
- "traefik.http.routers.{{service_name}}.entrypoints=web"
- "traefik.http.services.{{service_name}}.loadbalancer.server.port={{container_port}}"6. How to Test
Run the automated test suite:
python tests/test_nextjs_runtime.pyExpected output:
=== Running Next.js Runtime (F2.1) Automated Test Suite ===
Testing Next.js detection via config files...
[PASS] Auto-detected via next.config.js
[PASS] Auto-detected via next.config.mjs
[PASS] Auto-detected via next.config.ts
[PASS] Auto-detected via next.config.cjs
Testing Next.js detection via package.json dependencies...
[PASS] Auto-detected via package.json dependencies
Testing package manager lockfile resolution for Next.js...
[PASS] pnpm-lock.yaml -> build: 'pnpm run build', start: 'pnpm run start'
[PASS] yarn.lock -> build: 'yarn build', start: 'yarn start'
[PASS] bun.lockb -> build: 'bun run build', start: 'bun run start'
[PASS] package-lock.json -> build: 'npm run build', start: 'npm run start'
Testing next.yml template rendering & parameters...
[PASS] next.yml rendered correctly with all variables & labels
[SUCCESS] ALL NEXT.JS RUNTIME TESTS PASSED SUCCESSFULLY!