13. React-приложение в Docker
React-приложение требует двух этапов: сборка статических файлов (требует Node.js, npm, все dev-зависимости) и раздача статики (достаточно легковесного nginx). Multi-stage build идеально подходит для этого случая.
Стратегия контейнеризации React
Заголовок раздела «Стратегия контейнеризации React»React SPA (Single Page Application) компилируется в набор статических HTML, CSS и JS файлов. Для их раздачи в продакшене использует nginx — высокопроизводительный веб-сервер, образ которого всего ~25 MB.
Dockerfile для React приложения
Заголовок раздела «Dockerfile для React приложения»# ─── Этап 1: Сборка ────────────────────────────────FROM node:20-alpine AS buildWORKDIR /app
# Сначала зависимости (кеш)COPY package*.json ./RUN npm ci
# Потом кодCOPY . .
# Аргумент сборки для API URLARG REACT_APP_API_URL=https://api.example.comENV REACT_APP_API_URL=$REACT_APP_API_URL
RUN npm run build# Результат: /app/build
# ─── Этап 2: Nginx ─────────────────────────────────FROM nginx:1.25-alpine AS production
# Скопировать собранное приложениеCOPY --from=build /app/build /usr/share/nginx/html
# Кастомная конфигурация nginxCOPY nginx.conf /etc/nginx/conf.d/default.conf
# Nginx работает от непривилегированного пользователяEXPOSE 80
HEALTHCHECK --interval=30s --timeout=3s \ CMD wget -qO- http://localhost/health || exit 1
CMD ["nginx", "-g", "daemon off;"]Конфигурация Nginx для React Router
Заголовок раздела «Конфигурация Nginx для React Router»Если приложение использует React Router (client-side routing), nginx должен перенаправлять все запросы на index.html:
server { listen 80; server_name localhost; root /usr/share/nginx/html; index index.html;
# Сжатие gzip on; gzip_types text/plain text/css application/json application/javascript text/xml;
# Кеширование статики location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { expires 1y; add_header Cache-Control "public, immutable"; }
# Роутинг SPA — все пути на index.html location / { try_files $uri $uri/ /index.html; }
# Health check endpoint location /health { return 200 "healthy\n"; add_header Content-Type text/plain; }}.dockerignore для React проекта
Заголовок раздела «.dockerignore для React проекта»node_modules/build/.git/.gitignore.env.env.local.env.*.local*.lognpm-debug.log*README.md.DS_StoreDockerfile*docker-compose*Передача environment variables в React
Заголовок раздела «Передача environment variables в React»React встраивает переменные окружения на этапе сборки (build time), а не во время выполнения. Переменные с префиксом REACT_APP_ попадают в бандл.
# Передача API URL при сборкеARG REACT_APP_API_URLARG REACT_APP_VERSION
ENV REACT_APP_API_URL=${REACT_APP_API_URL:-http://localhost:3001}ENV REACT_APP_VERSION=${REACT_APP_VERSION:-dev}
RUN npm run build# Сборка с конкретными переменнымиdocker build \ --build-arg REACT_APP_API_URL=https://api.prod.com \ --build-arg REACT_APP_VERSION=1.2.3 \ -t myapp:prod .Docker Compose для разработки и продакшена
Заголовок раздела «Docker Compose для разработки и продакшена»services: frontend-dev: build: context: . dockerfile: Dockerfile.dev # с hot reload ports: - "3000:3000" volumes: - .:/app - /app/node_modules environment: - REACT_APP_API_URL=http://localhost:3001
frontend-prod: build: context: . target: production args: REACT_APP_API_URL: https://api.example.com ports: - "80:80"