Билд SPA приложения без SSR, в нашем случае это Vite.js + React, представляет собой набор статических файлов, с отдачей которых справится базовая настройка Nginx с минимальными изменениями.
В нашем случае мы используем Webmin/Virtualmin для настройки, но это не особо влияет на саму конфигурацию.
Для запуска SPA приложения на базовой конфигурации Nginx сервера, нам не хватает нескольких моментов:
- Переадресация всех путей на наш рут, /index.html в данном случае;
- Зарезервированный путь для получения/обновления SSL сертификатов.
Переадресация путей
Тут нам надо исправить 2 момента:
#Установим root и точку входа, у нас index.html в папка dist
root /home/my_domain/my_domain/dist/;
index index.html;
# Укажем, как обрабатывать пути, кроме статических файлов (отбор по расширениям)
location / {
if (-f $request_filename) {
expires max;
break;
}
if ($request_filename !~ "\.(js|htc|ico|gif|jpg|png|css)$") {
rewrite ^(.*) /index.html last;
}
}
Получение/обновление SSL
В данном случае мы используем Let’s Encrypt, Webmin для автоматической работы с этими сертификатами использует папку /.well-known, соответственно выделяем ее так, что бы она не обрабатывалась нашим SPA — например меняем для этого location root.
location /.well-known/ {
root /home/my_domain/public_html;
}
Итоговый шаблон
server {
server_name my_domain.ru www.my_domain.ru;
# your server IP
listen 00.00.00.00;
root /home/my_domain/my_domain/dist/;
index index.html;
access_log /var/log/virtualmin/my_domain.ru_access_log;
error_log /var/log/virtualmin/my_domain.ru_error_log;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_FILENAME /home/my_domain/public_html$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT /home/my_domain/public_html;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param HTTPS $https;
location /.well-known/ {
root /home/my_domain/public_html;
}
location / {
if (-f $request_filename) {
expires max;
break;
}
if ($request_filename !~ "\.(js|ico|gif|jpg|png|css)$") {
rewrite ^(.*) /index.html last;
}
}
# your server IP
listen 00.00.00.00:443 ssl;
ssl_certificate /etc/ssl/virtualmin/PATH_TO_KEY/ssl.combined;
ssl_certificate_key /etc/ssl/virtualmin/PATH_TO_KEY/ssl.key;
}
Итого
Очевидно, что все папки и адреса Вам необходимо заменить на собственные, но идея остается прежней: перехватываем все пути и замыкаем на index.html, а отдельные служебные пути выделяем в location и оставляем например в стандартной public_html для удобства.
Так же при необходимости использования API с этого же сервера, Вы можете самостоятельно добавить location по типу /api/ и сделать редирект на обработчик например.