# syntax=docker/dockerfile:1
# Backend Node service local development — hot reload via volume mounts + tsx watch
# GENERATED by composable.env (ce init / scaffold:sync).
FROM node:24-bookworm-slim
# bookworm (not alpine) — backend services often pull native deps
# (better-sqlite3, sharp, @resvg/resvg-js, native crypto modules) that
# need glibc, not musl.

# Corepack enabled; the actual pnpm version comes from package.json's
# packageManager field (via `corepack install` below), so Docker builds
# never drift from the host's pinned version. Projects without
# packageManager get a clear MissingPackageManagerError — pin one in
# package.json (the modern convention).
RUN corepack enable

# Caddy for in-container TLS termination when profile.tls is true.
# Debian 12 ships caddy 2.x in main — no third-party apt repo needed.
# (Unused for proxy: "caddy" / "caddy-external" profiles where a
# host-level or per-project Caddy fronts everything.)
RUN apt-get update && apt-get install -y --no-install-recommends caddy ca-certificates \
  && rm -rf /var/lib/apt/lists/*

WORKDIR /app

# Pre-install COPY: package.json drives the corepack install. .npmrc*
# is a glob — safe whether or not the project has one because the
# guaranteed-match sources alongside keep the COPY non-empty.
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc* ./
RUN corepack install

# Wholesale workspace COPY — any new packages/<x>/ is picked up
# automatically; no per-package enumeration to forget (the recurring
# break in hand-rolled backend Dockerfiles before this template).
COPY apps/ ./apps/
COPY packages/ ./packages/

# Optional pnpm patches/ dir (pnpm patchedDependencies). Bind-mounting
# the build context lets us conditionally copy without erroring when
# the dir is absent. Must run BEFORE `pnpm install` so the patches are
# present at patchedDependencies resolution time.
RUN --mount=type=bind,source=.,target=/ctx,readonly \
    if [ -d /ctx/patches ]; then \
      mkdir -p ./patches && cp -r /ctx/patches/. ./patches/; \
    fi

RUN pnpm install --frozen-lockfile

# Build shared library packages so backend services can import their
# dist/ outputs (tsx watch in dev mode doesn't pre-build deps). Scoped
# to ./packages/* — apps are NOT built here, because app builds (next
# build, etc.) need runtime context (NEXT_PUBLIC env, data sources,
# Sentry tokens) that the backend service image doesn't have. Apps
# build at their own time, via their own image entrypoint or dev mode.
# --if-present skips packages without a build script.
RUN pnpm -r --filter "./packages/*" --if-present run build

# Entrypoint bypasses turbo so Docker env vars pass through to the app
COPY docker/app-entrypoint.sh /usr/local/bin/app-entrypoint.sh

# Source comes from volume mounts in dev — overlays the COPYed dirs
# docker-compose volumes: ["./apps/myservice:/app/apps/myservice"]
# Port binding via docker-compose `ports:`, not EXPOSE here — services
# bind different ports and that's a per-contract concern.

# command: in docker-compose passes the pnpm filter name as $1
ENTRYPOINT ["/usr/local/bin/app-entrypoint.sh"]
