# API service Dockerfile for {{projectName}}'s Node-based api apps.
#
# Build context = project root (where pnpm-workspace.yaml lives).
# The `.dockerignore` next to this file aggressively excludes noise.
#
# Build args:
#   APP_PATH  — path relative to context where the api lives.
#               e.g. apps/{{projectName}}/api
#
# Targets:
#   prod  — production image (this file's only target; dev uses
#           node:24-alpine directly via docker-compose.dev.yml so
#           code mounts work without an image-build step).
#
# Build:
#   docker build \
#     -f docker/api.Dockerfile \
#     --build-arg APP_PATH=apps/{{projectName}}/api \
#     -t {{projectName}}-api:latest \
#     .

ARG NODE_VERSION=24-alpine
ARG PNPM_VERSION=10.25.0
ARG APP_PATH=apps/{{projectName}}/api

# ---------- deps stage ----------
FROM node:${NODE_VERSION} AS deps
ARG PNPM_VERSION
RUN corepack enable && corepack prepare pnpm@${PNPM_VERSION} --activate
WORKDIR /workspace

# Copy ONLY what pnpm install needs — lockfile + workspace manifests.
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./
COPY apps apps
COPY packages packages

RUN pnpm install --frozen-lockfile

# ---------- builder stage ----------
FROM deps AS builder
ARG APP_PATH
WORKDIR /workspace/${APP_PATH}
RUN pnpm voltro codegen . || true
# Precompile the api into the SERVE BUNDLE so `voltro serve` boots from one
# artefact and NEVER transpiles on demand. NOT best-effort: a bundle-build failure
# is fatal (no `|| true`) so the image never silently falls back to the slow tsx
# path — production must serve from the bundle.
RUN pnpm voltro build .
# Isolate a prod-only, self-contained tree for THIS app (drops devDependencies,
# the pnpm store, and every other app), then carry the precompiled bundle in.
# Only the driver for THIS app's DB dialect is included (a memory store ships
# none). `--no-optional` also drops @voltro/cli's BUILD toolchain (tsx/esbuild/
# vite/tailwind + their native tree) — declared as optionalDependencies so a
# serve-only prod install excludes them; production serves from the bundle and
# never transpiles, so the image stays lean with no fragile prune list.
WORKDIR /workspace
RUN APP_NAME=$(node -p "require('/workspace/${APP_PATH}/package.json').name") \
 && pnpm --filter="${APP_NAME}" --prod --no-optional --legacy deploy /deploy \
 ; cp -r /workspace/${APP_PATH}/.framework /deploy/.framework 2>/dev/null || echo "no .framework (serve loads from source)"

# ---------- prod runner ----------
FROM node:${NODE_VERSION} AS prod
ARG PNPM_VERSION
RUN corepack enable && corepack prepare pnpm@${PNPM_VERSION} --activate
WORKDIR /app
COPY --from=builder /deploy /app
EXPOSE 4000
ENV NODE_ENV=production
# `voltro serve` is the ONE production entrypoint — it auto-detects the app kind
# and runs the API server. `voltro start` is web-only and aborts an API app at
# boot with "no web app found at this path".
CMD ["pnpm", "voltro", "serve", "."]
