FROM node:24.21.0-bookworm-slim AS base WORKDIR /app FROM base AS dependencies # Native SQLite/bcrypt builds happen only here; compilers stay out of runtime. RUN apt-get update && apt-get install -y --no-install-recommends python3=3.11.2-1+b1 make=4.3-4.1 g++=4:12.2.0-3 ca-certificates=20250419~deb12u1 openssl=3.0.20-1~deb12u2 && rm -rf /var/lib/apt/lists/* COPY package.json package-lock.json ./ RUN npm ci COPY . . RUN npx --no-install prisma generate FROM dependencies AS development # Nest watch uses ps to stop the previous process tree before restarting. RUN apt-get update && apt-get install -y --no-install-recommends procps=2:4.0.2-3 && rm -rf /var/lib/apt/lists/* RUN mkdir /data && chown node:node /data && chown -R node:node /app USER node ENV NODE_ENV=development DATABASE_URL=file:/data/wealthledger.db EXPOSE 3000 CMD ["npm", "run", "start:dev"] FROM dependencies AS build # The client is already generated at the shared dependencies stage (same revision). RUN npx --no-install nest build && npm prune --omit=dev --omit=optional FROM base AS production RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates=20250419~deb12u1 openssl=3.0.20-1~deb12u2 && rm -rf /var/lib/apt/lists/* \ && mkdir /data && chown node:node /data ARG VERSION ARG REVISION LABEL org.opencontainers.image.version=$VERSION \ org.opencontainers.image.revision=$REVISION COPY --from=build /app/node_modules ./node_modules COPY --from=build /app/dist ./dist COPY --from=build /app/prisma ./prisma COPY --from=build /app/prisma.config.ts ./prisma.config.ts COPY --from=build /app/package.json /app/package-lock.json ./ ENV NODE_ENV=production DATABASE_URL=file:/data/wealthledger.db USER node EXPOSE 3000 CMD ["node", "dist/src/main.js"] HEALTHCHECK --interval=10s --timeout=3s --start-period=20s --retries=6 \ CMD node -e 'fetch("http://127.0.0.1:3000/api/v1/auth/me").then(async r=>{await r.arrayBuffer();process.exit(r.status===401?0:1)}).catch(()=>process.exit(1))'