Деплой React на Nginx — пошаговая инструкция

React SPA после сборки — это статические HTML, CSS и JS файлы. Nginx отлично подходит для такой раздачи. Главная тонкость — настроить fallback на index.html, чтобы React Router не давал 404 при обновлении страницы.

Деплой React на Nginx по шагам

Базовый деплой React на Nginx состоит из трёх частей: собрать статические файлы, положить их на сервер и настроить fallback для SPA. Если забыть fallback, главная страница может работать, а внутренние маршруты будут отдавать 404.

Если приложение собрано через Vite или CRA, на сервер попадает уже не исходный код React, а статические HTML, JS и CSS. Поэтому Nginx не запускает React, а только отдаёт готовую сборку.

Собрать проект

# Vite
npm run build
# результат: dist/

# Create React App
npm run build
# результат: build/

Скопировать файлы на сервер

sudo mkdir -p /var/www/my-react-app
sudo cp -r dist/* /var/www/my-react-app/

Конфиг Nginx для SPA

server {
    listen 80;
    server_name example.com;

    root /var/www/my-react-app;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|svg|ico|woff2?)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}

Активировать сайт

sudo ln -s /etc/nginx/sites-available/my-react-app /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Серверные сценарии после базового деплоя

После первого успешного деплоя обычно появляются дополнительные вопросы: Docker, подпапка, API, кэширование, CDN. Эти сценарии лучше разбирать отдельно, потому что каждый меняет конфигурацию Nginx и способ сборки приложения.

Эти настройки лучше добавлять после того, как простая версия уже работает. Тогда понятно, какая именно новая задача сломала поведение: подпапка, proxy_pass, Docker, кэширование или маршруты SPA.

Docker-вариант

FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80

Типичные проблемы

  • 404 при обновлении страницы — нет try_files с fallback на index.html.
  • Белый экран — неверный base в vite.config.js при деплое в подпапку.
  • Старые файлы не обновляются — проверьте кэширование HTML и статики.
  • API-запросы не работают — настройте proxy_pass или правильный API URL.

Деплой в подпапку

Если приложение будет открываться не в корне домена, а например на /app/, Vite нужно заранее сказать базовый путь. Иначе ссылки на JS и CSS могут вести не туда.

// vite.config.js
export default defineConfig({
  base: '/app/',
  plugins: [react()],
});

Проксировать API через Nginx

Часто React лежит на том же домене, что и API. Тогда Nginx отдаёт статику, а запросы /api проксирует на backend.

location /api/ {
    proxy_pass http://127.0.0.1:3001/api/;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}

Кэширование HTML и статики

HTML лучше не кэшировать надолго, потому что он указывает на актуальные JS-файлы. А файлы с хэшами в имени можно кэшировать долго.

  • index.html — короткий cache-control.
  • assets/*.js и assets/*.css с хэшами — долгий immutable cache.
  • После деплоя проверяйте страницу в режиме инкогнито.
  • Если используется CDN, сбрасывайте кэш после релиза.

Финальная проверка деплоя на Nginx

Самая частая ошибка после деплоя React SPA — главная страница открывается, а внутренняя ссылка или обновление страницы дают 404. Это почти всегда проблема серверного fallback на index.html.

Проверять нужно не только главную страницу. Откройте внутренний маршрут напрямую, обновите страницу, проверьте загрузку assets, API-запросы и поведение после очистки кэша. Именно эти шаги показывают, что деплой действительно готов.

Проверочный список

  • откройте главную страницу приложения;
  • перейдите на внутренний маршрут через меню;
  • обновите страницу на этом внутреннем маршруте;
  • откройте тот же URL в новой вкладке;
  • проверьте, что JS и CSS грузятся не с localhost.

Если приложение лежит в подпапке

Для адреса вроде /app/ настройте base в vite.config.js до сборки. Если забыть base, HTML может загрузиться, но ссылки на ассеты будут вести в неправильное место.

Что делать с API

Лучше не зашивать production API URL в компонентах. Вынесите адрес в переменные окружения или проксируйте /api через Nginx на backend. Так проще менять окружения без правки кода.

Оцените статью
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x