49 lines
1.6 KiB
Docker
49 lines
1.6 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 ----------
|
|
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 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"]
|