# ── Stage 1: Build client ─────────────────────────────────────────────────── FROM node:20-alpine AS client-builder WORKDIR /build COPY package.json ./ COPY client/package.json ./client/ COPY server/package.json ./server/ RUN npm install --workspace=client COPY client/ ./client/ RUN npm run build --workspace=client # ── Stage 2: Build server ─────────────────────────────────────────────────── FROM node:20-alpine AS server-builder WORKDIR /build COPY package.json ./ COPY server/package.json ./server/ RUN npm install --workspace=server COPY server/ ./server/ RUN npm run build --workspace=server # ── Stage 3: Runtime ──────────────────────────────────────────────────────── FROM node:20-alpine AS runtime WORKDIR /app ENV NODE_ENV=production ENV PORT=3000 ENV DATA_DIR=/data ENV MAX_UPLOAD_MB=50 ENV ADMIN_USERNAME=admin ENV ADMIN_PASSWORD=codedump2024 ENV JWT_SECRET=changeme-use-a-long-random-string # Install production deps only COPY package.json ./ COPY server/package.json ./server/ RUN npm install --workspace=server --omit=dev # Copy built artifacts COPY --from=server-builder /build/server/dist ./server/dist COPY --from=client-builder /build/client/dist ./client/dist VOLUME ["/data"] EXPOSE 3000 HEALTHCHECK --interval=30s --timeout=5s --start-period=10s \ CMD wget -qO- http://localhost:3000/api/settings || exit 1 CMD ["node", "server/dist/index.js"]