# syntax=docker/dockerfile:1.7 # # Cyclone frontend — React SPA built with node:20-alpine and served by # nginx:1.27-alpine. nginx reverse-proxies /api/* to the backend service # over the compose-managed bridge network. # ---------- builder ---------- FROM node:20-alpine AS builder WORKDIR /build # Install deps first so this layer caches across source edits. COPY package.json package-lock.json* ./ RUN npm ci # Build the production bundle into dist/. COPY . . RUN npm run build # ---------- runtime ---------- FROM nginx:1.27-alpine # Replace the default nginx site with ours (SPA + reverse proxy). RUN rm -f /etc/nginx/conf.d/default.conf COPY nginx.conf /etc/nginx/conf.d/default.conf COPY --from=builder /build/dist /usr/share/nginx/html # wget is on busybox; nginx:alpine doesn't ship curl. HEALTHCHECK --interval=30s --timeout=5s --retries=3 \ CMD wget -qO- http://localhost:8080/ >/dev/null || exit 1 EXPOSE 8080