# syntax=docker/dockerfile:1.7 # ─── Stage 1: build React ──────────────────────────────────────── FROM node:20-alpine AS builder WORKDIR /app # Устанавливаем зависимости (кэшируется слой) COPY package.json package-lock.json ./ # npm install (а не ci), т.к. lock-файл может быть рассинхронизирован RUN npm install --no-audit --no-fund --legacy-peer-deps # Копируем исходники COPY public ./public COPY src ./src ENV GENERATE_SOURCEMAP=false \ DISABLE_ESLINT_PLUGIN=true \ NODE_OPTIONS=--max_old_space_size=4096 RUN npm run build # ─── Stage 2: runtime (nginx) ──────────────────────────────────── FROM nginx:1.27-alpine AS runtime # nginx сам запустит envsubst для шаблона перед стартом ENV NGINX_ENVSUBST_TEMPLATE_SUFFIX=.template \ NGINX_ENVSUBST_OUTPUT_DIR=/etc/nginx/conf.d \ BACKEND_URL=http://backend:8000 # Убираем дефолтный конфиг, кладём наш шаблон RUN rm /etc/nginx/conf.d/default.conf COPY docker/nginx/default.conf.template /etc/nginx/templates/default.conf.template # Билд статики COPY --from=builder /app/build /usr/share/nginx/html EXPOSE 80 HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ CMD wget -qO- http://localhost/ > /dev/null 2>&1 || exit 1 # Точка входа от nginx-image уже знает про templates