Деплой React и Vite: nginx, маршруты SPA и кэш
Как собрать React-приложение, настроить nginx для вложенных маршрутов, разделить кэш HTML и assets и разместить сайт в Inquir Compute.
После npm run build React-приложение на Vite становится набором HTML, JavaScript и CSS. Для выдачи этих файлов не нужен постоянно работающий Vite dev server. Ниже — контейнер с nginx для Inquir Compute, который корректно открывает вложенные маршруты SPA.
Разделите сборку и выдачу файлов
Проверьте, что локально выполняются npm ci и npm run build, а результат появляется в dist. Если проект использует другой build.outDir, измените путь копирования в Dockerfile. Команда vite preview предназначена для проверки сборки локально, а не для рабочего сервера — см. руководство Vite.
FROM node:22-bookworm-slim AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginxinc/nginx-unprivileged:stable-alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/dist/ /usr/share/nginx/html/
EXPOSE 8080
Для воспроизводимых рабочих релизов зафиксируйте проверенные версии или digest образов. В .dockerignore исключите .env, node_modules, .git и локальный dist, чтобы сборка не зависела от файлов на ноутбуке.
Настройте маршруты и кэш
Создайте nginx.conf:
server {
listen 8080;
server_name _;
root /usr/share/nginx/html;
index index.html;
absolute_redirect off;
location = /healthz {
default_type text/plain;
return 200 "ok\n";
}
location /assets/ {
add_header Cache-Control "public, max-age=31536000, immutable";
try_files $uri =404;
}
location / {
add_header Cache-Control "no-cache";
try_files $uri $uri/ /index.html;
}
}
Fallback на index.html нужен для прямого перехода на /settings/profile, который обрабатывает React Router. Но отсутствующий JavaScript-файл в /assets/ должен возвращать 404: HTML вместо JavaScript приводит к ошибкам MIME или Unexpected token '<'.
Годовой кэш подходит только файлам с хэшем содержимого в имени. HTML должен перепроверяться, чтобы браузер получил ссылки на новую сборку. Не применяйте immutable ко всему сайту.
Разместите сайт в Inquir
После настройки CLI выполните из каталога проекта:
inquir apps create react-site --ingress public --port 8080 --health-path /healthz
inquir apps deploy react-site --promote
inquir apps status react-site
На адресе из status проверьте главную, прямое открытие вложенного маршрута и обновление страницы на нём. Путь должен существовать в вашем роутере; nginx не создаёт отсутствующие React-страницы. Отдельно запросите несуществующий /assets/missing.js — ожидается 404.
Переменные Vite не являются секретами
Значения VITE_*, используемые клиентским кодом, включаются в сборку и видны посетителю. В них допустим публичный адрес API, но не пароль базы и не ключ провайдера моделей. Изменение переменной уже запущенного nginx не переписывает собранный JavaScript: нужен новый build либо специально реализованная загрузка публичной конфигурации во время запуска.
Если API находится на другом домене, разрешите нужный origin в CORS на API. Не пытайтесь исправить серверные права доступа только настройкой фронтенда. Для своего домена используйте документацию приложений; полный стартовый проект доступен в static-react-vite.