# syntax=docker/dockerfile:1 # --------------------------------------------------------------------------- # deps: complete dependency tree, shared by the build and the dev target. # Stays on the full node image because better-sqlite3 needs a toolchain. # --------------------------------------------------------------------------- FROM node:22 AS deps WORKDIR /app COPY package*.json ./ RUN npm ci # --------------------------------------------------------------------------- # dev: watch-mode target used by compose.yaml. Keeps devDependencies so # tsx, drizzle-kit and next dev are available. Sources come from bind mounts. # --------------------------------------------------------------------------- FROM deps AS dev ENV NODE_ENV=development COPY . . RUN mkdir -p data EXPOSE 3000 3001 CMD ["npm", "run", "dev:api"] # --------------------------------------------------------------------------- # build: compile the API to dist/ and the frontend to .next/, then drop # devDependencies so the runtime stage carries only what it executes. # --------------------------------------------------------------------------- FROM deps AS build ENV NEXT_TELEMETRY_DISABLED=1 # Next.js resolves next.config.mjs rewrites at build time and writes the literal # destination into .next/routes-manifest.json. Setting API_INTERNAL_URL only at # runtime has no effect on `next start`, so the API address of the target # topology has to be known here. Server components read the variable at runtime. ARG API_INTERNAL_URL=http://localhost:3000 ENV API_INTERNAL_URL=$API_INTERNAL_URL COPY . . RUN npm run build:api && npm run build:web RUN npm prune --omit=dev # --------------------------------------------------------------------------- # prod: runtime image. node:22-slim shares the Debian release of the build # stage, so the compiled better-sqlite3 binding stays loadable. # --------------------------------------------------------------------------- FROM node:22-slim AS prod ENV NODE_ENV=production ENV NEXT_TELEMETRY_DISABLED=1 WORKDIR /app COPY --from=build --chown=node:node /app ./ RUN mkdir -p data && chown node:node data USER node EXPOSE 3000 3001 CMD ["node", "dist/server/index.js"]