Как установить и настроить Astro на VPS
Современные фреймворки вроде React или Vue грузят на клиента весь свой рантайм, даже если на странице всего пара интерактивных виджетов — и Lighthouse честно показывает эту цену в мегабайтах JS. Astro решает проблему иначе: по умолчанию он вообще не отправляет JavaScript в браузер, а интерактивность добавляется точечно, только там, где она реально нужна. Показываю, как поставить Astro на свой VPS, разобраться с «островной» архитектурой и настроить рабочий деплой.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что такое Astro и почему у него нулевой JS по умолчанию
Astro — генератор сайтов, который на этапе сборки превращает компоненты (собственный .astro-формат, а также React, Vue, Svelte, Solid — почти что угодно) в статический HTML. Ключевое отличие от «обычных» SPA-фреймворков: сгенерированная страница по умолчанию не содержит вообще никакого JavaScript. Компонент отрендерился в разметку один раз при сборке — и всё, дальше это просто HTML и CSS.
Интерактивность добавляется явно, компонент за компонентом, через директивы client:*:
---
import Counter from '../components/Counter.jsx';
---
<Counter client:load />
<Counter client:visible />
<Counter client:idle />
Каждый такой компонент называют «островом» — изолированным кусочком интерактивности на статическом «океане» HTML. client:load гидрирует компонент сразу при загрузке страницы, client:visible — когда он появляется в области видимости (полезно для виджетов ниже первого экрана), client:idle — когда браузер освободится от более приоритетной работы. Компоненты без директивы вообще не попадают в JS-бандл клиента — их HTML отрисован на сервере, и на этом их жизненный цикл заканчивается.
Практический смысл: на странице с лендингом, галереей и одной формой обратной связи в браузер уедет JS только формы — не весь фреймворк ради неё. Это отличает Astro от Hugo или Jekyll, где вообще нет собственной модели компонентов с интерактивностью — там пришлось бы городить отдельный JS-виджет руками. Если у вас чисто статический контент без интерактива вообще, вероятно, хватит и более простого генератора — сравнение подходов есть в статье Hugo: статический сайт, установка и деплой. Astro имеет смысл брать, когда часть страниц статична, а часть требует локальной интерактивности (карусели, фильтры, формы, счётчики) без превращения всего сайта в SPA.
Установка Node.js и Astro на сервер
В отличие от Hugo (один бинарник на Go) или Jekyll (Ruby), Astro — инструмент из экосистемы Node.js, и сама сборка требует Node на машине, где вы собираете проект. Через apt в репозиториях Ubuntu обычно лежит устаревшая версия, поэтому надёжнее ставить через NodeSource:
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo bash -
sudo apt install -y nodejs
node -v
npm -v
Актуальную поддерживаемую версию Node на конец августа 2026 года уточните на nodesource.com — Astro следует релизному циклу Node LTS, и его требования к минимальной версии со временем растут, конкретную цифру я специально не фиксирую.
Альтернатива, если на сервере уже крутится несколько проектов с разными версиями Node — nvm, чтобы не конфликтовать с системным пакетом:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
source ~/.bashrc
nvm install --lts
nvm use --lts
Сам Astro отдельно ставить не нужно — он идёт как зависимость проекта и создаётся сразу вместе со скелетом сайта:
npm create astro@latest
Мастер спросит имя папки, шаблон (пустой, блог, портфолио или готовый пример), нужен ли TypeScript и стоит ли сразу поставить зависимости и инициализировать git — на сервере обычно удобнее собирать проект локально и заливать на VPS уже готовым, но ничего не мешает поднять весь цикл прямо на сервере, если он используется как единственная машина разработки.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверСтруктура проекта
После создания проекта вы получаете такой набор каталогов:
myastro/
├── astro.config.mjs # конфигурация: интеграции, адаптеры, site URL
├── package.json
├── src/
│ ├── pages/ # каждый файл = отдельный маршрут сайта
│ │ ├── index.astro
│ │ └── blog/
│ │ └── post-1.md
│ ├── components/ # переиспользуемые .astro/.jsx/.vue-компоненты
│ ├── layouts/ # обёртки для страниц (шапка, футер, meta)
│ └── content/ # Content Collections — типизированный Markdown/MDX
├── public/ # файлы как есть: favicon, robots.txt, изображения
└── dist/ # сюда попадает результат сборки
src/pages/— файловый роутинг:src/pages/about.astroстановится страницей/about/, аsrc/pages/blog/[slug].astro— динамическим маршрутом.src/content/— Content Collections, механизм Astro для типизированного контента: описываете схему (через Zod) вsrc/content/config.ts, и дальше сборка проверяет, что во всех Markdown-файлах коллекции есть нужные поля с правильными типами. Удобно, если статьи пишет не только один человек и хочется ловить опечатки в front matter на этапе сборки, а не после деплоя.astro.config.mjs— здесь подключаются интеграции (@astrojs/react,@astrojs/tailwind,@astrojs/sitemapи т.д.) и, при необходимости, адаптер для серверного рендеринга.
Локальный просмотр с live-reload:
npm run dev
Сайт поднимется на http://localhost:4321 — порт по умолчанию у Astro, в отличие от привычных 3000 или 8080 у других инструментов.
Сборка в статику и когда нужен адаптер
По умолчанию Astro работает в режиме output: 'static' — команда сборки генерирует чистый HTML/CSS/JS без необходимости в бэкенде:
npm run build
Результат — папка dist/ с готовыми файлами, которые можно отдавать любым веб-сервером, вообще без Node.js в продакшене. Это тот же принцип, что и у Hugo с Jekyll: тяжёлая работа сделана один раз при сборке, а дальше сервер просто раздаёт файлы с диска.
Если часть страниц всё же нуждается в серверной логике на каждый запрос (персонализация, авторизация, данные, которые нельзя закешировать статически) — Astro поддерживает гибридный режим через output: 'server' или output: 'hybrid' (в последних версиях — output: 'static' с точечным export const prerender = false в конкретных страницах). Для этого нужен адаптер под конкретную среду выполнения:
npx astro add node
Адаптер @astrojs/node разворачивает Node.js-сервер, который придётся держать процессом (через pm2 или systemd), а не просто раздавать статику через Nginx. Для большинства блогов, документации и лендингов серверный режим не нужен — если явной причины для него нет, оставайтесь на output: 'static', это ощутимо проще в эксплуатации на своём VPS.
Nginx отдаёт готовые файлы
Для статической сборки конфиг Nginx короткий — как и у любого генератора, который отдаёт файлы с диска, а не проксирует запросы в приложение:
server {
listen 80;
server_name example.com www.example.com;
root /var/www/myastro/dist;
index index.html;
location / {
try_files $uri $uri/index.html $uri.html =404;
}
location = /404.html {
internal;
}
error_page 404 /404.html;
# хешированные ассеты Astro кешируются агрессивно и безопасно —
# имя файла меняется при каждой правке содержимого
location ~* ^/_astro/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
Каталог _astro/ — это скомпилированные JS-острова и CSS с хешами в имени файла, поэтому их можно кешировать сколь угодно долго без риска отдать читателю устаревшую версию: при следующей сборке имя файла изменится само. После конфига — обычный certbot --nginx для HTTPS. Если предпочитаете Caddy, авто-SSL там из коробки и конфиг ещё компактнее — процесс описан в статье Как установить и настроить Caddy с авто-SSL на VPS. Порты для входящего трафика стоит сразу открыть через фаервол — см. Фаервол UFW на Ubuntu 24.04: пошаговая установка, если ещё не настраивали.
Автоматический деплой при изменении контента
Собирать npm run build руками и копировать dist/ на сервер после каждой правки быстро надоедает. Для одного VPS без внешнего CI рабочий вариант — git hook прямо на сервере.
Заводим bare-репозиторий:
mkdir -p /var/repo/myastro.git
cd /var/repo/myastro.git
git init --bare
Хук /var/repo/myastro.git/hooks/post-receive:
#!/bin/bash
WORK_TREE=/var/www/myastro-src
PUBLIC_DIR=/var/www/myastro/dist
git --work-tree=$WORK_TREE --git-dir=/var/repo/myastro.git checkout -f main
cd $WORK_TREE
npm ci
npm run build
rsync -a --delete dist/ $PUBLIC_DIR/
echo "Деплой завершён: $(date)"
chmod +x /var/repo/myastro.git/hooks/post-receive
npm ci вместо npm install — важный нюанс: он ставит зависимости строго по package-lock.json, без пересчёта дерева, что и быстрее, и предсказуемее для сервера, где вы не хотите неожиданно словить новую минорную версию пакета прямо на проде.
Локально:
git remote add prod ssh://user@your-server/var/repo/myastro.git
git push prod main
Сборка Node-проекта заметно тяжелее по CPU и памяти, чем у Hugo — если VPS минимальной конфигурации, первая сборка с холодным node_modules может занять заметно дольше, чем у генераторов без npm-экосистемы; конкретное время сильно зависит от количества зависимостей и мощности сервера, так что ориентируйтесь на свои замеры. Если сборки станут регулярно упираться в RAM (OOM во время npm run build на VPS с 1 ГБ), проще либо временно поднять своп, либо собирать проект на более мощной машине и заливать на сервер уже готовый dist/ через rsync без сборки на месте. Про более сложные сценарии деплоя (несколько окружений, откат на предыдущую версию) — в статье автодеплой из git на сервере: частые ошибки и решения.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Нужен ли Node.js на сервере в продакшене?
Нет, если используется режим output: 'static' (по умолчанию) — Node нужен только на этапе сборки. Готовые файлы в dist/ отдаёт любой веб-сервер без какого-либо рантайма позади. Node.js на проде понадобится, только если включён серверный или гибридный режим через адаптер.
Чем Astro отличается от Next.js или чистого React?
Next.js по умолчанию гидрирует всю страницу целиком, даже статичные её части. Astro гидрирует только явно помеченные client:*-компоненты, а весь остальной HTML остаётся без JS — на сопоставимом контенте это обычно означает заметно меньший объём JS, отправляемого в браузер, хотя точная разница зависит от конкретного сайта и его интерактивных элементов.
Можно ли использовать React-компоненты в Astro?
Да, через официальную интеграцию @astrojs/react (аналогично для Vue, Svelte, Solid, Preact) — можно даже комбинировать разные фреймворки на одной странице, каждый компонент гидрируется независимо.
Сколько RAM нужно под сборку Astro на VPS?
Сама сборка требовательна к CPU и RAM на короткое время, особенно на проектах с большим количеством зависимостей и изображений для оптимизации — для небольшого блога обычно достаточно 1-2 ГБ, но при регулярных OOM во время npm run build стоит либо добавить своп, либо перенести сборку на более мощную машину.
Что делать, если после деплоя видна старая версия сайта?
Проверьте, что скрипт деплоя реально перезаписал dist/ (флаг --delete у rsync обязателен, иначе удалённые страницы останутся висеть), и что браузер или CDN перед сервером не отдают закешированную версию index.html — сам index.html кешировать агрессивно не стоит, в отличие от хешированных файлов из _astro/.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →