# syntax=docker/dockerfile:1.7 FROM node:22-alpine AS builder WORKDIR /app # Alpine needs build tools for better-sqlite3 native module. # vips-dev provides libvips + libheif for sharp (incl. HEIC input from iOS). RUN apk add --no-cache python3 make g++ libc6-compat vips-dev COPY package*.json ./ # Bewusst npm install (nicht npm ci): der package-lock.json wird auf dem # Dev-System (Windows) generiert und markiert die linux-musl-arm64-Prebuilts # von sharp als "dev": true, sodass npm ci sie nicht installiert. npm install # resolvt Optional-Deps frisch fuer die aktuelle Plattform (= linux-arm64-musl # im Docker-Build) und findet die Prebuilts korrekt. Die package.json-semver- # Ranges sorgen fuer hinreichende Reproduzierbarkeit. RUN npm install --include=optional --no-audit --no-fund COPY . . RUN npm run build # Fresh-Install fuer den Runtime-Stage: nur Produktions-Deps, wieder mit # npm install statt ci aus demselben Grund wie oben. RUN rm -rf node_modules \ && npm install --omit=dev --include=optional --no-audit --no-fund FROM node:22-alpine AS runner WORKDIR /app RUN apk add --no-cache libc6-compat COPY --from=builder /app/build ./build COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/package.json ./package.json ENV NODE_ENV=production ENV HOST=0.0.0.0 ENV PORT=3000 ENV DATABASE_PATH=/data/kochwas.db ENV IMAGE_DIR=/data/images VOLUME ["/data"] EXPOSE 3000 HEALTHCHECK --interval=15s --timeout=5s --retries=3 --start-period=20s --start-interval=2s \ CMD wget -qO- http://127.0.0.1:3000/api/health > /dev/null || exit 1 CMD ["node", "build/index.js"]