geocrop-platform./apps/nextgen/Dockerfile

52 lines
1.7 KiB
Docker

# syntax=docker/dockerfile:1
# ---------- Stage 1: build the React/Vite client ----------
FROM node:20-alpine AS client-build
WORKDIR /app/client
COPY client/package*.json ./
RUN npm ci
COPY client/ .
RUN npm run build
# ---------- Stage 2: install production server deps (native module build) ----------
# Debian slim (glibc) — better-sqlite3 has no glibc prebuilt binary for this
# version, so we compile it with build-essential + python3.
FROM node:20-slim AS server-deps
RUN apt-get update && apt-get install -y --no-install-recommends python3 make g++ \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app/server
COPY server/package*.json ./
RUN npm ci --omit=dev
# ---------- Stage 3: runtime image ----------
FROM node:20-slim
RUN apt-get update && apt-get install -y --no-install-recommends tini && rm -rf /var/lib/apt/lists/*
WORKDIR /app
ENV NODE_ENV=production \
PORT=3001 \
DB_PATH=/app/data/school.db
# Server source + production node_modules
COPY server/ ./server/
COPY --from=server-deps /app/server/node_modules ./server/node_modules
# Built client, served statically by the Express server
COPY --from=client-build /app/client/dist ./client/dist
COPY docker-entrypoint.sh ./docker-entrypoint.sh
RUN chmod +x docker-entrypoint.sh \
&& mkdir -p /app/data /app/server/uploads \
&& groupadd -g 1001 appgroup && useradd -u 1001 -g appgroup -s /bin/sh -m appuser \
&& chown -R appuser:appgroup /app
USER appuser
EXPOSE 3001
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \
CMD node -e "require('http').get('http://localhost:3001/api/health',r=>{process.exit(r.statusCode===200?0:1)}).on('error',()=>process.exit(1))"
ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["./docker-entrypoint.sh"]