Проект на Vite в режиме разработки опирается на dev-сервер с HMR, проксированием модулей и динамической трансформацией кода. Для деплоя на VPS требуется финальная статическая сборка, которая формируется командой сборки.
npm run build
После выполнения команды создаётся каталог dist,
содержащий оптимизированные ресурсы: JavaScript-бандлы, CSS, шрифты,
изображения и HTML-точку входа. Важная особенность Vite — хеширование
файлов, что позволяет безопасно настраивать агрессивное кэширование на
уровне nginx.
Внутренняя структура dist обычно выглядит следующим
образом:
dist/
assets/
index-8f3a1c2d.js
index-4b91d1e6.css
index.html
Каждый файл в assets содержит уникальный hash, зависящий
от содержимого. Это исключает необходимость ручного управления
версионированием статики.
После сборки содержимое dist переносится на сервер. На
практике используются rsync или scp.
rsync -avz dist/ user@server_ip:/var/www/vite-app
или
scp -r dist/* user@server_ip:/var/www/vite-app
На сервере заранее создаётся директория для проекта:
mkdir -p /var/www/vite-app
Важный момент — переносится только результат сборки, без
node_modules и исходного кода, так как nginx работает со
статическими файлами.
На большинстве Linux-дистрибутивов установка выполняется стандартным пакетным менеджером.
apt update
apt install nginx
После установки сервис запускается автоматически:
systemctl status nginx
Корневая директория nginx по умолчанию:
/var/www/html
Однако для отдельных приложений создаётся собственный server block.
Для Vite-приложения создаётся отдельный конфиг:
nano /etc/nginx/sites-available/vite-app
Пример конфигурации:
server {
listen 80;
server_name example.com;
root /var/www/vite-app;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
Активация сайта:
ln -s /etc/nginx/sites-available/vite-app /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx
Vite часто используется для SPA-приложений (React, Vue, Svelte). В
таком случае маршрутизация обрабатывается на клиенте, а nginx должен
всегда отдавать index.html, если файл не найден.
Ключевая директива:
try_files $uri $uri/ /index.html;
Поведение:
/assets/index.js — отдаётся
файл/dashboard — возвращается
index.htmlБез этой настройки при обновлении страницы на внутренних маршрутах возникает 404 ошибка.
Vite генерирует файлы с хешами, поэтому можно безопасно включать долгосрочное кэширование.
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
Для HTML-каркаса кэширование отключается:
location /index.html {
expires -1;
add_header Cache-Control "no-cache";
}
Такое разделение позволяет ускорить загрузку без риска устаревших версий приложения.
Сжатие снижает объём передаваемых данных, особенно для JS-бандлов.
Активация gzip:
gzip on;
gzip_types text/plain text/css application/javascript application/json;
gzip_min_length 1000;
Если доступен brotli-модуль:
brotli on;
brotli_types text/plain text/css application/javascript application/json;
Vite уже генерирует оптимизированный код, но серверное сжатие остаётся критически важным для производительности.
Для production-развёртывания добавляются базовые HTTP-заголовки:
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY;
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy no-referrer-when-downgrade;
При необходимости можно включить Content Security Policy:
add_header Content-Security-Policy "default-src 'self'; script-src 'self'";
Для доменного имени подключается SSL-сертификат через certbot.
Установка:
apt install certbot python3-certbot-nginx
Получение сертификата:
certbot --nginx -d example.com
После выполнения автоматически добавляется HTTPS-конфигурация:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
root /var/www/vite-app;
location / {
try_files $uri $uri/ /index.html;
}
}
Дополнительно добавляется редирект HTTP → HTTPS:
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
При размещении приложения не в корне домена требуется настройка
base в vite.config.js.
export default {
base: "/app/"
}
В nginx аналогично:
location /app/ {
try_files $uri $uri/ /app/index.html;
}
Несоответствие base и nginx-конфигурации приводит к
ошибкам загрузки ассетов.
Vite подставляет переменные на этапе сборки. Это означает, что изменение API-адреса требует новой сборки:
VITE_API_URL=https://api.example.com
Для VPS-деплоя часто используется разделение окружений:
.env.production.env.stagingПосле изменения переменных выполняется повторный билд и обновление
dist.
Причина — отсутствие try_files для SPA. Решение —
корректная маршрутизация на index.html.
Причина часто связана с неправильным base в Vite.
Проверяется соответствие путей в index.html.
Обычно вызван:
Проверка выполняется через nginx error.log и DevTools
браузера.
Основные логи:
/var/log/nginx/access.log
/var/log/nginx/error.log
Просмотр в реальном времени:
tail -f /var/log/nginx/error.log
При проблемах с маршрутизацией или отдачей файлов логирование является основным источником диагностики.
Обновление сводится к замене содержимого dist:
rsync -avz --delete dist/ user@server:/var/www/vite-app
Благодаря хешированным ассетам старые файлы не конфликтуют с новыми, а переход происходит мгновенно после перезагрузки страницы.
При необходимости минимизации риска используется промежуточная директория:
/var/www/releases/20260529_01/
и переключение symlink:
/var/www/current -> /var/www/releases/20260529_01
nginx указывает на /var/www/current.