sadrix logoSadriX
Минцифры готовит обязательную регистрацию IMEI смартфонов, купленных за границей
Гайды

Как раздать React SPA через Nginx: пошаговая инструкция

От сборки билда до готового конфига с fallback на index.html

08 001 просмотров5 мин
0
Поделиться:TelegramVK

Введение

Одностраничные приложения (SPA) на React после сборки превращаются в набор статических файлов: HTML, CSS, JavaScript и медиа. Чтобы пользователи могли открывать их по красивым URL и чтобы работал клиентский роутинг (React Router), нужен веб-сервер, который правильно отдаёт статику и перенаправляет все «неизвестные» запросы на index.html. Nginx — самый популярный выбор для этой задачи благодаря производительности, гибкости и простоте настройки.

В этом гайде мы пройдём путь от собранного билда до рабочего конфига Nginx, который корректно раздаёт SPA, кэширует ресурсы, сжимает ответы и защищает от типичных ошибок. Инструкция подойдёт для большинства хостингов: от VPS с Ubuntu до Docker-контейнеров.

Требования

  • Сервер с установленным Nginx (версия 1.18+). Для локальной проверки можно использовать Docker.

  • Собранное React-приложение (папка build или dist после npm run build).

  • Базовые навыки работы с командной строкой и SSH.

  • Доступ к конфигурации Nginx (обычно /etc/nginx/).

  • (Опционально) Доменное имя, указывающее на IP сервера.

Шаг 1: Соберите React-приложение

Убедитесь, что в проекте настроен скрипт сборки. Выполните в корне проекта:

npm run build

После завершения появится папка build (Create React App) или dist (Vite). Внутри — index.html и подпапка static с хешированными ресурсами. Именно эту папку мы будем раздавать.

Важно: если приложение будет размещено в подкаталоге (например, https://example.com/app/), настройте homepage в package.json или base в конфиге Vite до сборки.

Шаг 2: Установите Nginx на сервер

Для Ubuntu/Debian:

sudo apt update
sudo apt install nginx -y

Для CentOS/RHEL:

sudo yum install epel-release -y
sudo yum install nginx -y

Проверьте, что сервис запущен:

sudo systemctl status nginx

Шаг 3: Разместите файлы сборки на сервере

Создайте каталог для сайта, например /var/www/my-spa, и скопируйте туда содержимое папки сборки. Это можно сделать через scp, rsync или Git.

Пример с локальной машины:

rsync -avz build/ user@server:/var/www/my-spa/

Убедитесь, что у Nginx есть права на чтение файлов. Обычно достаточно владельца www-data или прав 755 на каталоги и 644 на файлы.

Шаг 4: Создайте конфигурационный файл Nginx

Создайте новый файл в /etc/nginx/sites-available/my-spa.conf (или в /etc/nginx/conf.d/ в зависимости от дистрибутива). Пример базовой конфигурации:

server {
    listen 80;
    server_name example.com www.example.com;

    root /var/www/my-spa;
    index index.html;

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

Ключевая директива — try_files $uri $uri/ /index.html;. Она говорит Nginx: сначала попробуй отдать запрошенный файл, затем — как каталог, а если ничего не найдено — верни index.html. Это и обеспечивает работу клиентского роутинга.

Шаг 5: Активируйте сайт и проверьте конфигурацию

Если используете sites-available/sites-enabled, создайте символическую ссылку:

sudo ln -s /etc/nginx/sites-available/my-spa.conf /etc/nginx/sites-enabled/

Проверьте синтаксис:

sudo nginx -t

Если ошибок нет, перезагрузите Nginx:

sudo systemctl reload nginx

Теперь откройте домен в браузере — приложение должно загрузиться.

Шаг 6: Настройте кэширование статических ресурсов

Файлы в папке static имеют хеш в имени, поэтому их можно кэшировать надолго. Добавьте в конфиг:

location /static/ {
    expires 1y;
    add_header Cache-Control "public, immutable";
}

Для index.html кэш лучше отключить, чтобы пользователи получали свежую версию:

location = /index.html {
    add_header Cache-Control "no-cache, no-store, must-revalidate";
}

Шаг 7: Включите сжатие (gzip)

Сжатие уменьшает размер передаваемых файлов. В блоке http (обычно в /etc/nginx/nginx.conf) или в вашем server добавьте:

gzip on;
gzip_types text/plain text/css application/javascript application/json image/svg+xml;
gzip_min_length 1024;
gzip_comp_level 6;

Не сжимайте уже сжатые форматы (изображения, шрифты) — это бесполезно.

Шаг 8: Настройте HTTPS с Let's Encrypt (рекомендуется)

Для безопасности используйте бесплатный сертификат. Установите Certbot:

sudo apt install certbot python3-certbot-nginx -y

Запустите автоматическую настройку:

sudo certbot --nginx -d example.com -d www.example.com

Certbot сам изменит конфиг, добавив SSL-сертификаты и редирект с HTTP на HTTPS. После этого проверьте автообновление:

sudo certbot renew --dry-run

Шаг 9: Добавьте базовую защиту и оптимизацию

Рекомендуемые директивы в блоке server:

server_tokens off;  # скрыть версию Nginx
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";

Для отдачи больших файлов можно включить sendfile on; и tcp_nopush on; в блоке http.

Шаг 10: Проверьте работу роутинга

Откройте в браузере любой внутренний маршрут, например https://example.com/about. Страница должна загрузиться без ошибки 404. Если вы видите 404 — значит, директива try_files не сработала. Проверьте, что она находится именно в location / и что нет других location, перехватывающих запросы.

Шаг 11: Настройте логирование и мониторинг

Убедитесь, что логи пишутся в доступные файлы. По умолчанию это /var/log/nginx/access.log и error.log. Для отладки можно временно повысить уровень логов в блоке server:

error_log /var/log/nginx/my-spa-error.log warn;

Шаг 12: Оптимизируйте для production (опционально)

  • Используйте HTTP/2 (включается автоматически с HTTPS в современных версиях Nginx).

  • Настройте client_max_body_size, если приложение загружает файлы.

  • Рассмотрите brotli вместо gzip для лучшего сжатия (требует установки модуля).

Типичные ошибки

1. 404 при обновлении страницы на внутреннем маршруте — забыта директива try_files или она перекрыта другим location. 2. Неправильные пути к статике — если приложение собрано с homepage, файлы могут запрашиваться по другому URL. Проверьте консоль браузера. 3. Кэширование index.html — приводит к тому, что пользователи видят старую версию после деплоя. Убедитесь, что для index.html стоит no-cache. 4. Отсутствие прав доступа — Nginx не может прочитать файлы, если они принадлежат другому пользователю и нет прав на чтение. 5. Конфликт с другими сайтами — если на сервере несколько server блоков, убедитесь, что server_name уникален и запросы попадают в нужный блок. 6. Игнорирование HTTPS — современные браузеры могут блокировать некоторые функции (например, геолокацию) без HTTPS.

FAQ

Вопрос: Можно ли раздать SPA без `try_files`? Ответ: Нет, без этого клиентский роутинг не будет работать при прямом переходе по ссылке. Сервер должен возвращать index.html для всех маршрутов, кроме существующих файлов.

Вопрос: Как раздать SPA из подкаталога? Ответ: Используйте location /app/ { alias /var/www/my-spa/; try_files $uri $uri/ /app/index.html; } и соберите приложение с соответствующим base или homepage.

Вопрос: Нужно ли настраивать CORS? Ответ: Если API находится на другом домене, настройте CORS на стороне API. Nginx может проксировать запросы к API, чтобы избежать CORS, но это отдельная задача.

Вопрос: Как обновлять приложение без простоя? Ответ: Собирайте новую версию в отдельную папку, затем атомарно переключайте симлинк и перезагружайте Nginx. Или используйте rsync с последующим nginx -s reload.

Вопрос: Поддерживает ли Nginx сжатие Brotli? Ответ: Да, но требуется установка дополнительного модуля. В стандартных сборках доступен только gzip.

Итог

Мы рассмотрели полный процесс настройки Nginx для раздачи React SPA: от сборки приложения до готового конфига с поддержкой роутинга, кэширования, сжатия и HTTPS. Ключевой момент — директива try_files, которая обеспечивает корректную работу клиентских маршрутов. Следуя шагам, вы получите производительную и безопасную конфигурацию, готовую к продакшену. Не забывайте проверять конфиг через nginx -t и тестировать приложение после каждого изменения.

Читайте также

Комментарии

Комментарии доступны только зарегистрированным пользователям. Войти

  • Пока нет комментариев. Будьте первым.