Как раздать React SPA через Nginx: пошаговая инструкция
От сборки билда до готового конфига с fallback на index.html
Введение
Одностраничные приложения (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.comCertbot сам изменит конфиг, добавив 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 и тестировать приложение после каждого изменения.
Читайте также
Комментарии
Комментарии доступны только зарегистрированным пользователям. Войти
- Пока нет комментариев. Будьте первым.



