diff --git a/Workflow/.dockerignore b/Workflow/.dockerignore new file mode 100644 index 0000000..b903cfb --- /dev/null +++ b/Workflow/.dockerignore @@ -0,0 +1,67 @@ +# ───────────────────────────────────────────────────────────────── +# .dockerignore — keep the build context small and secret-free. +# +# Critical: without this file the whole local working tree is sent to +# the Docker daemon, including .env.local (PB_TOKEN, CIPC passwords), +# node_modules and the full .git history. +# ───────────────────────────────────────────────────────────────── + +# --- secrets: never let these reach the build context --------------- +.env +.env.* +!.env.example + +# --- deps, build output, git history ---------------------------------- +node_modules +.next +out +dist +build +*.tsbuildinfo +.git +.gitignore +.gitattributes + +# --- logs & runtime state -------------------------------------------- +*.log +*.log.err +*.tmp +.runtime +.dev-screenshots +npm-debug.log* + +# --- local databases -------------------------------------------------- +*.sqlite +*.sqlite3 +*.db + +# --- secrets inside scripts/ ------------------------------------------ +# Playwright storage state = live CIPC/SARS session cookies. +scripts/storage_state.json + +# --- scratch, compiled python, debug artefacts ------------------------ +__pycache__ +**/__pycache__ +*.py[cod] +*.bin +scripts/.scratch +scripts/_scratch +scripts/_backup_ufc_docs +scripts/_*.png +scripts/sars_login_*.png +scripts/_upload_probe.pdf +_probe*.json +_junction_backup*.json + +# --- docs, samples and one-off probes (not needed to serve the app) --- +docs +scratch-* +Sample_*.docx +Sample_*.pdf +*.preview-p*.png +.preview-p*.png +workpage*.png +desktop.ini +Thumbs.db +*.bak +*.bak.* \ No newline at end of file diff --git a/Workflow/Dockerfile b/Workflow/Dockerfile index 10a8cf9..53d5941 100644 --- a/Workflow/Dockerfile +++ b/Workflow/Dockerfile @@ -1,5 +1,5 @@ # ───────────────────────────────────────────────────────────────── -# Workflow PocketBase Frontend — Dockerfile +# Workflow PocketBase Frontend — Dockerfile (Coolify-ready) # # Multi-stage build for a small production image: # - deps: install everything @@ -9,14 +9,23 @@ # # Image runs as non-root user `nextjs` on port 3000. # -# Build context: project root (where package.json lives). -# Example: -# docker build -t workflow-frontend . -# docker run --rm -p 3000:3000 \ -# -e NEXT_PUBLIC_BASE_URL=https://workflow.example.co.za \ -# -e PB_URL=https://pb.agent.apphub.co.za \ -# -e PB_TOKEN=... \ -# workflow-frontend +# Build context: this folder (where package.json lives). +# Local: docker build -t workflow-frontend . +# docker run --rm -p 3000:3000 \ +# -e PB_URL=https://pb.agent.apphub.co.za \ +# -e PB_TOKEN=... \ +# workflow-frontend +# +# Coolify: set "Dockerfile" as the build pack, port 3000, and configure +# Build Arguments (NEXT_PUBLIC_PB_URL, NEXT_PUBLIC_BASE_URL, +# NEXT_PUBLIC_APP_URL) + Runtime Environment (PB_URL, PB_TOKEN, +# TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID, ONBOARDING_TOKEN_PEPPER). +# See docker-compose.yml for the same contract in one place. +# +# NOTE — routes that shell out to local Windows tooling do NOT work in +# this Linux image: the CIPC/BizPortal routes drive agent-browser and the +# BizPortal sidecar, and PDF rendering expects a Windows Chrome or the +# PDFD_URL sidecar. They stay on the PC; host them separately. # ───────────────────────────────────────────────────────────────── # ─── 1. Deps ───────────────────────────────────────────────────── @@ -34,14 +43,26 @@ WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . . -# Required at build-time so Next.js bakes the public URL into the -# client bundle. PB_TOKEN is NOT required here — it's only read -# server-side at runtime. +# Required at build-time so Next.js bakes them into the client bundle. +# Next.js INLINES every NEXT_PUBLIC_* at build time — if they are missing +# here, the browser bundle ships with an empty PocketBase URL and every +# client-side PB call fails. Set them as Build Arguments in Coolify. +# +# NEXT_PUBLIC_PB_URL — read by components/CipcAnnualReturns.tsx and +# components/DocumentsPanel.tsx +# NEXT_PUBLIC_BASE_URL — read by app/onboarding/new/page.tsx (link the +# client sends in the onboarding e-mail) +# NEXT_PUBLIC_APP_URL — absolute app URL used in appointment e-mails +# +# Server-only secrets (PB_URL, PB_TOKEN, TELEGRAM_*, ONBOARDING_TOKEN_PEPPER) +# are NOT needed here — they are read at runtime, never bundled. +ARG NEXT_PUBLIC_PB_URL ARG NEXT_PUBLIC_BASE_URL -ENV NEXT_PUBLIC_BASE_URL=${NEXT_PUBLIC_BASE_URL} - -# Disable telemetry; speeds up build; we don't need it. -ENV NEXT_TELEMETRY_DISABLED=1 +ARG NEXT_PUBLIC_APP_URL +ENV NEXT_PUBLIC_PB_URL=${NEXT_PUBLIC_PB_URL} \ + NEXT_PUBLIC_BASE_URL=${NEXT_PUBLIC_BASE_URL} \ + NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL} \ + NEXT_TELEMETRY_DISABLED=1 RUN npm run build diff --git a/Workflow/docker-compose.yml b/Workflow/docker-compose.yml index 11dfc75..6e3231a 100644 --- a/Workflow/docker-compose.yml +++ b/Workflow/docker-compose.yml @@ -16,8 +16,11 @@ services: context: . dockerfile: Dockerfile args: - # Bake the public URL into the client bundle at build time. + # Baked into the CLIENT bundle by Next.js at build time — all three + # must be set or browser-side PocketBase calls get an empty URL. + NEXT_PUBLIC_PB_URL: ${NEXT_PUBLIC_PB_URL:-https://pb.agent.apphub.co.za} NEXT_PUBLIC_BASE_URL: ${NEXT_PUBLIC_BASE_URL:-http://localhost:3000} + NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL:-http://localhost:3000} image: workflow-frontend:latest container_name: workflow-frontend restart: unless-stopped @@ -29,6 +32,8 @@ services: PB_URL: ${PB_URL:?Set PB_URL in .env} PB_TOKEN: ${PB_TOKEN:?Set PB_TOKEN in .env} ONBOARDING_TOKEN_PEPPER: ${ONBOARDING_TOKEN_PEPPER:-} + TELEGRAM_BOT_TOKEN: ${TELEGRAM_BOT_TOKEN:-} + TELEGRAM_CHAT_ID: ${TELEGRAM_CHAT_ID:-} NODE_ENV: production PORT: 3000 HOSTNAME: 0.0.0.0