57 lines
2.0 KiB
Docker
57 lines
2.0 KiB
Docker
# syntax=docker/dockerfile:1.7
|
|
# Cyclone frontend — Vite/React SPA built once and served by nginx.
|
|
#
|
|
# Multi-stage so node_modules + build cache (~hundreds of MB) don't ship
|
|
# in the runtime image. The final image is nginx:alpine serving the
|
|
# pre-built static bundle, with /api/* reverse-proxied to the backend
|
|
# service over the compose network.
|
|
#
|
|
# Build context is the repo root (../) so package.json / vite config /
|
|
# src/ are all reachable from the docker-compose `dockerfile:` directive.
|
|
|
|
# ---- build stage --------------------------------------------------------
|
|
FROM node:20-alpine AS build
|
|
|
|
WORKDIR /app
|
|
|
|
# Copy manifests first so dependency layer caches when only source changes.
|
|
COPY package.json package-lock.json* /app/
|
|
RUN npm ci --no-audit --no-fund
|
|
|
|
# Source + build configs. VITE_API_BASE_URL is left empty so the SPA
|
|
# calls /api/* on the same origin (handled by nginx in the runtime stage).
|
|
COPY index.html postcss.config.js tailwind.config.js \
|
|
tsconfig.json tsconfig.app.json tsconfig.node.json \
|
|
vite.config.ts /app/
|
|
COPY public /app/public
|
|
COPY src /app/src
|
|
|
|
ENV NODE_ENV=production \
|
|
VITE_API_BASE_URL=
|
|
|
|
RUN npm run build
|
|
|
|
# ---- runtime stage ------------------------------------------------------
|
|
FROM nginx:1.27-alpine AS runtime
|
|
|
|
# Drop the default nginx site and ship ours (SPA fallback + /api proxy).
|
|
RUN rm /etc/nginx/conf.d/default.conf
|
|
COPY frontend/nginx.conf /etc/nginx/conf.d/cyclone.conf
|
|
|
|
# Static bundle from the build stage.
|
|
COPY --from=build /app/dist /usr/share/nginx/html
|
|
|
|
# nginx:alpine ships with a non-root `nginx` user (UID 101). We stay as
|
|
# root only long enough to write the pid + cache dirs, then exec under
|
|
# that user. This avoids permission issues with mounted volumes.
|
|
RUN touch /var/run/nginx.pid \
|
|
&& chown -R nginx:nginx /var/run/nginx.pid /var/cache/nginx /usr/share/nginx/html
|
|
|
|
USER nginx
|
|
|
|
EXPOSE 80
|
|
|
|
HEALTHCHECK --interval=15s --timeout=3s --start-period=5s --retries=3 \
|
|
CMD wget --quiet --tries=1 --spider http://127.0.0.1/ || exit 1
|
|
|
|
CMD ["nginx", "-g", "daemon off;"] |