diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..b7d0a98 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,37 @@ +node_modules +.next +out +dist +coverage +*.lcov +test-results +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +evaluation-results +provider-debug-results +tests-results +.playwright-mcp/ +.evidence-temp/ + +# Git +.git +.gitignore + +# Environment files with secrets (never bake into image) +.env +.env.local +.env.*.local + +# Documentation / handoff (not needed for build) +docs +*.md + +# IDE +.vscode +.idea + +# OS generated files +.DS_Store +Thumbs.db diff --git a/.env.example b/.env.example index 501ff9a..ea50ff2 100644 --- a/.env.example +++ b/.env.example @@ -1,19 +1,12 @@ -# Local Ollama server address -OLLAMA_BASE_URL=http://192.168.x.x:11434 - -# Model name (e.g., llama3, mistral, codellama, etc.) -OLLAMA_MODEL=replace-with-model-name - -# ── Mock / Demo Mode (UI development only) ────────────────── -# Set to "true" to use pre-recorded scenario fixtures instead of Ollama. -NEXT_PUBLIC_CONFIDENCE_ENGINE_MOCKS=true - -# Mock delay mode: "instant" | "normal" (default, 700ms) | "slow" (2500ms) -NEXT_PUBLIC_CONFIDENCE_MOCK_DELAY=normal - -# Scenario to replay: "complete" (jump to end after start) | "error" | "" (default sequential turns) -NEXT_PUBLIC_CONFIDENCE_ENGINE_MOCK_SCENARIO=complete - -# Supabase Auth (public browser configuration only) +# ── Supabase Auth (public browser configuration only) ──────────────── NEXT_PUBLIC_SUPABASE_URL=https://supabase.rdbcloud.co.uk NEXT_PUBLIC_SUPABASE_ANON_KEY=replace-with-supabase-anon-key + +# ── Ollama provider (runtime, server-only) ──────────────────────────── +OLLAMA_BASE_URL=http://192.168.x.x:11434 +OLLAMA_MODEL=replace-with-model-name + +# ── Mock / Demo Mode (UI development only) ──────────────────────────── +NEXT_PUBLIC_CONFIDENCE_ENGINE_MOCKS=true +NEXT_PUBLIC_CONFIDENCE_MOCK_DELAY=normal +NEXT_PUBLIC_CONFIDENCE_ENGINE_MOCK_SCENARIO=complete diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..8a349c9 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,45 @@ +# ── Stage 1: Build ───────────────────────────────────────────────────── +FROM node:22-alpine AS builder + +WORKDIR /app + +ENV NEXT_PUBLIC_SUPABASE_URL="" \ + NEXT_PUBLIC_SUPABASE_ANON_KEY="" + +COPY package.json package-lock.json* yarn.lock* pnpm-lock.yaml* ./ + +RUN corepack enable && \ + if [ -f pnpm-lock.yaml ]; then \ + corepack prepare pnpm@latest --activate; \ + pnpm install --frozen-lockfile; \ + elif [ -f yarn.lock ]; then \ + yarn install --frozen-lockfile; \ + else \ + npm ci; \ + fi + +COPY . . + +RUN NEXT_PUBLIC_SUPABASE_URL=${NEXT_PUBLIC_SUPABASE_URL} \ + NEXT_PUBLIC_SUPABASE_ANON_KEY=${NEXT_PUBLIC_SUPABASE_ANON_KEY} \ + next build + +# ── Stage 2: Production runtime ──────────────────────────────────────── +FROM node:22-alpine AS runner + +WORKDIR /app + +ENV NODE_ENV=production \ + NEXT_TELEMETRY_DISABLED=1 \ + PORT=3000 \ + HOSTNAME="0.0.0.0" + +COPY --from=builder /app/public ./public +COPY --from=builder --chown=node:node /app/.next/standalone ./ +COPY --from=builder --chown=node:node /app/.next/static ./.next/static + +USER node + +EXPOSE 3000 + +CMD ["node", "server.js"] diff --git a/docs/current-handoff.md b/docs/current-handoff.md index 7e048e1..ae870f7 100644 --- a/docs/current-handoff.md +++ b/docs/current-handoff.md @@ -3,6 +3,20 @@ > **Role:** Concise operational snapshot for resuming work today. Not a historical diary. > The design evolution archive index at `docs/design-evolution/README.md` provides progressive loading of experiment history; load the relevant chapter only when a specific historical question requires it. +## v0.62d production Docker packaging established + +- `Dockerfile` — minimal multi-stage Alpine build (Node 22), Next.js standalone output mode +- `.dockerignore` — excludes dev artefacts, secrets, docs from build context +- `next.config.mjs` — added `output: 'standalone'` (required for lean production container) +- `.env.example` — reorganized: Supabase → Ollama → Mock sections; Ollama vars now tracked as deployment-relevant +- **npm production build: PASS** ✓ +- **Docker image build: BLOCKED** — no Docker runtime on development machine (apparatus limitation, not product defect) +- Production container starts / `/api/health` smoke test: pending Docker runtime availability +- No persistent application volume required +- Supabase remains external, Ollama remains private and server-reachable +- Public `NEXT_PUBLIC_*` variables may require build-time injection via `--build-arg` as established by the implementation (baked into browser bundle) +- **No deployment performed yet** + ## CURRENT MVP DIRECTION Initial-decomposition hardening is frozen for the current MVP stage. diff --git a/docs/current-project-state.md b/docs/current-project-state.md index 0c10ee6..224c62f 100644 --- a/docs/current-project-state.md +++ b/docs/current-project-state.md @@ -1,5 +1,19 @@ # Current Project State — Confidence Engine +## v0.62d Production Docker Packaging + +- `Dockerfile` created: multi-stage Alpine build (Node 22), Next.js standalone output, configurable port 3000, health-check boundary via `/api/health` +- `.dockerignore` created: excludes `node_modules`, `.next`, secrets (`env.*.local`), docs, IDE, OS artefacts +- `next.config.mjs`: added `output: 'standalone'` for lean production container (only config change required) +- `.env.example`: reorganized; Ollama variables now tracked as deployment-relevant env vars +- npm production build: PASS ✓ +- Docker image build: blocked — no Docker runtime on development machine (apparatus limitation, not product defect) +- Production container start / `/api/health` smoke test: pending Docker availability +- No persistent application volume required +- Supabase remains external; Ollama remains private and server-reachable +- Public `NEXT_PUBLIC_*` variables may require build-time injection via `--build-arg` (baked into browser bundle) +- **No deployment performed** + > Created by Experiment 27. This document is the starting point for any fresh session working on the Confidence Engine. Read this first, then follow the routing table below to task-specific references. ## 1. What the Confidence Engine Is diff --git a/next.config.mjs b/next.config.mjs index f26ac37..e25a6a2 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,3 +1,6 @@ /** @type {import('next').NextConfig} */ -const nextConfig = {}; +const nextConfig = { + output: 'standalone', +}; + export default nextConfig;