WORKFLOW-APP/Dockerfile
SJCoetz bb97fef453 feat: initialize full ysterbaard frontend application
Add complete production-ready Ysterbaard PocketBase registry browser frontend:
- Next.js 14 App Router with TypeScript, Tailwind CSS, and TanStack React Query
- Secure server-side PocketBase API proxy to avoid exposing superuser tokens
- Read-only directors and companies registry browse pages with search, filtering, and pagination
- Client onboarding workflow for creating and managing client submissions
- Docker container configuration for easy deployment
- All supporting UI components, utility functions, and configuration files
2026-07-23 19:10:47 +02:00

80 lines
3.2 KiB
Docker

# ─────────────────────────────────────────────────────────────────
# Workflow PocketBase Frontend — Dockerfile
#
# Multi-stage build for a small production image:
# - deps: install everything
# - builder: compile the Next.js app (writes standalone output)
# - runner: copy the standalone build + public assets + .next/static
# onto the alpine image
#
# 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
# ─────────────────────────────────────────────────────────────────
# ─── 1. Deps ─────────────────────────────────────────────────────
FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json* ./
RUN \
if [ -f package-lock.json ]; then npm ci; \
else npm install; \
fi
# ─── 2. Builder ──────────────────────────────────────────────────
FROM node:20-alpine AS builder
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.
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
RUN npm run build
# ─── 3. Runner ───────────────────────────────────────────────────
FROM node:20-alpine AS runner
WORKDIR /app
# wget is needed by the HEALTHCHECK below (not in node:20-alpine
# by default — busybox-extra ships it).
RUN apk add --no-cache wget
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
ENV PORT=3000
ENV HOSTNAME=0.0.0.0
# Non-root user
RUN addgroup --system --gid 1001 nodejs && \
adduser --system --uid 1001 nextjs
# Copy the standalone build (Next.js output tracing) + static assets
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
# Health check — Coolify / Docker can probe /api/pb/records/list and
# 401 / 500 is fine here (it means the app booted; PB may be
# unreachable but the proxy is running). A connection refused means
# the Next.js server hasn't bound yet.
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
CMD wget -qO- http://127.0.0.1:3000/api/pb/records/list?collection=ysterbaard_directors\&perPage=1 >/dev/null || exit 1
CMD ["node", "server.js"]