# --- Build --- FROM node:22-slim AS build # Prisma benötigt OpenSSL für seine Query-Engine. RUN apt-get update && apt-get install -y --no-install-recommends openssl \ && rm -rf /var/lib/apt/lists/* WORKDIR /app COPY package.json package-lock.json ./ COPY server/package.json ./server/ COPY web/package.json ./web/ RUN npm ci COPY server/prisma ./server/prisma RUN npx prisma generate --schema server/prisma/schema.prisma COPY server ./server COPY web ./web # Das Frontend landet laut vite.config.ts direkt in server/public. RUN npm run build --workspace=web \ && npx tsc -p server/tsconfig.json # --- Laufzeit --- FROM node:22-slim AS runtime RUN apt-get update && apt-get install -y --no-install-recommends openssl \ && rm -rf /var/lib/apt/lists/* WORKDIR /app ENV NODE_ENV=production COPY package.json package-lock.json ./ COPY server/package.json ./server/ COPY web/package.json ./web/ RUN npm ci --omit=dev && npm cache clean --force COPY server/prisma ./server/prisma RUN npx prisma generate --schema server/prisma/schema.prisma COPY --from=build /app/server/dist ./server/dist COPY --from=build /app/server/public ./server/public COPY docker-entrypoint.sh ./ RUN chmod +x docker-entrypoint.sh && chown -R node:node /app USER node EXPOSE 3000 HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \ CMD node -e "fetch('http://127.0.0.1:3000/api/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))" ENTRYPOINT ["./docker-entrypoint.sh"] CMD ["node", "server/dist/index.js"]