gendesign/tradein-mvp/frontend/Dockerfile
lekss361 f2c18f5216
All checks were successful
Deploy Trade-In / changes (push) Successful in 14s
Deploy Trade-In / build-browser (push) Successful in 43s
Deploy Trade-In / build-frontend (push) Successful in 2m32s
Deploy Trade-In / test (push) Successful in 3m57s
Deploy Trade-In / build-backend (push) Successful in 41s
Deploy Trade-In / deploy (push) Successful in 1m32s
Deploy Trade-In / deploy-status (push) Successful in 1s
Deploy Trade-In / perimeter-smoke (push) Successful in 1m41s
Метрика на корпоративном аккаунте и подтверждение прав в Яндекс.Вебмастере (#3530)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ8jqr4SFirX5tFLwdSrXh
2026-09-15 16:48:57 +00:00

113 lines
6.6 KiB
Docker
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Trade-In MVP frontend — Next.js 15 + React 19 + TanStack Query.
# Без Sentry/Tailwind/Leaflet/echarts — лёгкая версия только для trade-in.
# ---- deps ----
FROM node:24-alpine AS deps
WORKDIR /app
# Лок ОБЯЗАТЕЛЕН (без `*`): `npm ci` без него падает, и это правильно —
# отсутствие лока раньше молча давало `npm install`, т.е. состав зависимостей
# определялся датой сборки (#2770).
COPY package.json package-lock.json ./
# --legacy-peer-deps: React 19 peer-dep mismatches (как в соседнем frontend/).
RUN --mount=type=cache,target=/root/.npm \
npm ci --legacy-peer-deps --no-audit --no-fund
# ---- builder ----
FROM node:24-alpine AS builder
WORKDIR /app
ENV NEXT_TELEMETRY_DISABLED=1
# basePath + API-prefix baked-in во время build (Next.js — build-time only).
# В CI workflow для prod:
# --build-arg NEXT_PUBLIC_BASE_PATH=/trade-in
# --build-arg NEXT_PUBLIC_API_BASE_URL=/trade-in
# В локальном dev: оба пусто = no-op (same-origin).
ARG NEXT_PUBLIC_BASE_PATH=""
ENV NEXT_PUBLIC_BASE_PATH=$NEXT_PUBLIC_BASE_PATH
ARG NEXT_PUBLIC_API_BASE_URL=""
ENV NEXT_PUBLIC_API_BASE_URL=$NEXT_PUBLIC_API_BASE_URL
ARG NEXT_PUBLIC_ENABLE_PREVIEW=""
ENV NEXT_PUBLIC_ENABLE_PREVIEW=$NEXT_PUBLIC_ENABLE_PREVIEW
# Аналитика и SEO-верификация (Яндекс.Метрика, GA4, Яндекс.Вебмастер,
# Google Search Console) — тот же контракт, что у переменных выше: Next.js
# инлайнит NEXT_PUBLIC_* в статические бандлы на `npm run build`, runtime
# env их НЕ подхватит, поэтому это build-arg, а не рантайм-конфиг.
#
# ПУСТОЙ ДЕФОЛТ — ЧАСТЬ КОНТРАКТА ФРОНТА, не временная заглушка: пустое
# значение означает «счётчик/мета-тег не рендерится вообще» (весь
# соответствующий script/meta отсутствует в разметке) — так решает
# frontend-код, потребляющий эти env (Dockerfile сам их не читает).
#
# ЗАВЕДЕНЫ (15.09.2026, аккаунт info@meraocenka.ru): NEXT_PUBLIC_YM_ID —
# счётчик Метрики, NEXT_PUBLIC_YANDEX_VERIFICATION — токен подтверждения прав
# в Вебмастере. Пустыми остаются GA_ID и GOOGLE_VERIFICATION.
# Когда появятся остальные номера — порядок тот же:
# 1) вписать литералом в build-args джоба build-frontend
# (.forgejo/workflows/deploy-tradein.yml) — В ОБОИХ блоках, основном
# И retry-без-кеша, иначе ретрай молча уедет без счётчика;
# 2) пересобрать образ — смена значения ТРЕБУЕТ build (build-time bake),
# одной правки runtime-конфига на проде недостаточно.
ARG NEXT_PUBLIC_YM_ID=""
ENV NEXT_PUBLIC_YM_ID=$NEXT_PUBLIC_YM_ID
ARG NEXT_PUBLIC_GA_ID=""
ENV NEXT_PUBLIC_GA_ID=$NEXT_PUBLIC_GA_ID
ARG NEXT_PUBLIC_YANDEX_VERIFICATION=""
ENV NEXT_PUBLIC_YANDEX_VERIFICATION=$NEXT_PUBLIC_YANDEX_VERIFICATION
ARG NEXT_PUBLIC_GOOGLE_VERIFICATION=""
ENV NEXT_PUBLIC_GOOGLE_VERIFICATION=$NEXT_PUBLIC_GOOGLE_VERIFICATION
# Версия продукта («Мера») + короткий git SHA + дата сборки — ДОЛЖНЫ быть
# build-time ARG (не runtime env): Next.js инлайнит NEXT_PUBLIC_* в статические
# бандлы на `npm run build`, а этот build context (./tradein-mvp/frontend) не
# видит tradein-mvp/VERSION (он на уровень выше, вне build context) — источник
# правды читает CI ДО вызова `docker build` (.forgejo/workflows/deploy-tradein.yml,
# job build-frontend) и передаёт сюда готовыми значениями. Пустые дефолты — для
# локальной сборки без CI; фолбэк на "VERSION-файл/dev/дата сборки" делает уже
# frontend-код, потребляющий эти env (Dockerfile сам файл не читает).
ARG NEXT_PUBLIC_APP_VERSION=""
ENV NEXT_PUBLIC_APP_VERSION=$NEXT_PUBLIC_APP_VERSION
ARG NEXT_PUBLIC_BUILD_SHA=""
ENV NEXT_PUBLIC_BUILD_SHA=$NEXT_PUBLIC_BUILD_SHA
ARG NEXT_PUBLIC_BUILD_DATE=""
ENV NEXT_PUBLIC_BUILD_DATE=$NEXT_PUBLIC_BUILD_DATE
# CHANGELOG.md — источник для /versions (src/lib/changelog.ts). Живёт на
# уровень выше этого build context (tradein-mvp/CHANGELOG.md), поэтому CI
# копирует его СЮДА (tradein-mvp/frontend/CHANGELOG.md) непосредственно
# перед `docker build` (см. .forgejo/workflows/deploy-tradein.yml, job
# build-frontend) — `COPY . .` ниже подхватывает её автоматически вместе с
# остальным контекстом. Локальная сборка без этого шага CI просто не находит
# файл — readChangelog() уже умеет деградировать (пустая история), сам
# Docker-билд при этом не падает (см. glob-COPY в runner stage ниже).
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
# ---- runner ----
FROM node:24-alpine AS runner
WORKDIR /app
# HOSTNAME=0.0.0.0 — Next.js standalone server.js биндится по этому env.
# Без него Docker ставит HOSTNAME=<container-id> и сервер недоступен по
# имени сервиса из других контейнеров (Caddy → 502).
ENV NODE_ENV=production \
NEXT_TELEMETRY_DISABLED=1 \
HOSTNAME=0.0.0.0 \
PORT=3000
COPY --from=builder --chown=node:node /app/public ./public
COPY --from=builder --chown=node:node /app/.next/standalone ./
COPY --from=builder --chown=node:node /app/.next/static ./.next/static
# /versions — Server Component, statically prerendered at `npm run build`
# (see src/app/versions/page.tsx) — CHANGELOG.md's content is already baked
# into .next/standalone above. This is a defensive fallback ONLY, in case that
# page ever stops being static: glob (trailing `*`) makes it a no-op when the
# builder stage doesn't have the file either (local build without the CI
# pre-copy step, see builder stage comment above) — never fails the build.
COPY --from=builder --chown=node:node /app/CHANGELOG.md* ./
USER node
EXPOSE 3000
CMD ["node", "server.js"]