MAATRIX / Блог / Grav держит сайт на плоских файлах: чем это лучше и хуже WordPress

Grav держит сайт на плоских файлах: чем это лучше и хуже WordPress

MAATRIX

WordPress тянет за собой MySQL, регулярные бэкапы базы, обновления ядра и вечную головную боль с чужими плагинами, которые ломают друг друга. Grav решает эту проблему радикально — убирает базу данных вообще: весь контент лежит в обычных Markdown-файлах на диске. Разберём честно, что вы получаете взамен реляционной СУБД и что теряете, отказываясь от самой большой CMS-экосистемы в мире.

Что такое Grav и почему у него нет базы данных

Grav — это PHP-система, собранная поверх компонентов Symfony и шаблонизатора Twig, которую разработчики называют flat-file CMS. Ключевое отличие от WordPress не в языке (оба на PHP), а в модели хранения. WordPress с первого дня строится вокруг MySQL: посты, страницы, метаданные, настройки, комментарии, ревизии — всё это строки в таблицах wp_posts, wp_postmeta, wp_options и десятке других. Grav вместо этого хранит каждую страницу как файл .md с YAML frontmatter в начале — блоком метаданных между ---, за которым идёт обычный Markdown-текст.

Структура контента — это структура папок в user/pages/. Типичный проект выглядит так:

user/pages/
├── 01.home/
│   └── default.md
├── 02.about/
│   └── default.md
└── 03.blog/
    ├── _item/
    ├── 01.first-post/
    │   └── item.md
    └── 02.second-post/
        └── item.md

Числовой префикс (01., 02.) задаёт порядок в меню и убирается из итогового URL — 03.blog превращается в /blog/. Сам файл выглядит примерно так:

---
title: О проекте
menu: О нас
visible: true
---

# О проекте

Обычный **Markdown**-текст, который Grav прогонит через Twig-шаблон и отдаст как HTML.

Никакого CREATE TABLE, никакого wp-config.php с данными для подключения к MySQL. Рендеринг страницы — это чтение файла с диска, разбор YAML и Markdown, подстановка в Twig-шаблон и (в проде) сохранение результата в файловый кэш. Установить Grav можно на VPS, где вообще нет MySQL — только PHP-FPM и веб-сервер, что упрощает стек по сравнению со связкой из статьи про установку статического сайта на VPS, только с динамическим PHP-рендерингом поверх файлов вместо чисто статичного HTML.

Бэкапы: файлы вместо файлов плюс база

Это главная практическая причина, по которой на Grav вообще стоит смотреть. Полный бэкап сайта на WordPress — это два независимых артефакта, которые обязаны быть согласованы между собой: дамп базы и архив файлов.

# WordPress: два шага, которые должны совпасть по времени
mysqldump --single-transaction -u wp_user -p wordpress_db > db.sql
tar czf wp-files.tar.gz /var/www/site/wp-content /var/www/site/wp-config.php

Если дамп базы снят на пять минут позже архива файлов — можно получить пост, у которого файл-обложка уже удалён, а запись в wp_posts ещё ссылается на старый ID вложения. Восстановление требует поднять MySQL, залить дамп, дождаться, пока движок переиграет транзакции, и прогнать wp-cli search-replace по таблицам, потому что WordPress хранит абсолютные URL прямо в контенте и в wp_options (siteurl, home) — при переносе на другой домен старые ссылки без замены просто не откроются. Технику согласованного дампа без блокировки таблиц разбирали в статье про бэкап баз данных без остановки — для WordPress --single-transaction обязателен, если сайт не должен «залипать» на секунды бэкапа.

На Grav бэкап — это один архив одной директории:

tar czf grav-backup-$(date +%F).tar.gz /var/www/site/user

Внутри user/ — контент, конфиги, установленные темы и плагины (сами файлы, а не записи о них в БД). Восстановление — распаковать архив обратно, без шага «подними MySQL, залей дамп, проверь кодировку». Абсолютных URL в контенте, как правило, нет — Grav генерирует ссылки на основе структуры страниц, поэтому перенос на новый домен обычно не требует поиска-замены по всему тексту.

Второе следствие плоских файлов — совместимость с git. Весь user/pages/ можно положить под версионный контроль:

cd /var/www/site
git init
git add user/pages
git commit -m "content snapshot"

История правок контента становится историей коммитов — откат к прошлой версии страницы это git checkout конкретного файла, а не поиск нужной ревизии в таблице wp_posts через админку. Для команды, которая уже привыкла жить в git и деплоить сайты из репозитория, это естественное продолжение процесса, а не отдельная система бэкапов поверх основного воркфлоу.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать VPS под сайт

Производительность на простых сайтах: без похода в БД

На каждый обычный запрос WordPress должен сходить в MySQL минимум за самим постом, его метаданными, настройками темы и активными виджетами — это десятки SQL-запросов на страницу без кэша, которые движок собирает и отдаёт PHP. Отсюда и стандартная рекомендация ставить кэширующий плагин или объектный кэш (Redis, Memcached) поверх голого WordPress, а на уровне веб-сервера — кэширование через nginx, чтобы вообще не доходить до PHP и MySQL на большинстве запросов.

Grav устроен иначе: страница — это файл на диске, а не строка в таблице, поэтому «поход в БД» отсутствует как класс операций. Первый рендер страницы читает Markdown, разбирает YAML, прогоняет через Twig — и сохраняет готовый HTML в файловый кэш (по умолчанию в cache/, можно переключить на APCu, Redis или Memcached через конфиг). Повторные запросы к той же странице обычно отдаются из кэша без повторного разбора файлов. Для несложного сайта — блог, лендинг, документация, портфолио — это ощутимо меньше движущихся частей: не нужно подбирать innodb_buffer_pool_size под доступную память, не нужен отдельный процесс mysqld, который ест память и требует собственного мониторинга.

Важная оговорка: если WordPress правильно настроен с объектным кэшем и кэширующим плагином, разрыв в скорости отдачи готовой страницы сильно сокращается — оба варианта в итоге отдают закэшированный HTML. Разница проявляется не столько в холодной скорости под кэшем, сколько в объёме инфраструктуры, которую нужно поднять и поддерживать, чтобы до этого состояния дойти: у Grav путь короче, меньше сервисов и параметров для тюнинга. Точных цифр по разнице в миллисекундах здесь намеренно не привожу — она сильно зависит от сервера, темы и профиля нагрузки, без замера на своём проекте любое число будет лукавством.

Что вы теряете: экосистема плагинов, тем и готовых решений

Это обратная сторона, и её нужно проговорить без иллюзий. WordPress питается крупнейшей в мире CMS-экосистемой: официальный каталог плагинов исчисляется десятками тысяч записей, каталог тем — тоже, и на любую задачу — от SEO до бронирования столиков в ресторане — почти наверняка уже есть готовый плагин, который кто-то поддерживает годами. У Grav через GPM (Grav Package Manager) устанавливаются темы и плагины из собственного каталога проекта:

bin/gpm index
bin/gpm install admin
bin/gpm install seo-plugin

Но сам каталог — это сотни позиций, а не десятки тысяч. Практические последствия:

  • Интернет-магазин. WooCommerce на WordPress — зрелая платформа с оплатой, доставкой, налогами, тысячами интеграций. У Grav нет сопоставимого по зрелости e-commerce-решения — есть плагины для простых витрин, но полноценный шоп с корзиной и платёжными шлюзами придётся собирать самостоятельно или интегрировать внешний сервис.
  • Комментарии. У WordPress они встроены в ядро, плюс Akismet и анти-спам плагины. У Grav комментариев нет по умолчанию — обычная практика подключить сторонний виджет (Disqus, Isso, utterances на GitHub Issues), что добавляет внешнюю зависимость вместо встроенной функции.
  • SEO-инструменты. Yoast SEO и Rank Math на WordPress — комбайны с проверкой читаемости, автогенерацией sitemap, разметкой schema.org. У Grav есть SEO-плагин, но по глубине функциональности он не сопоставим — рассчитывайте на ручную настройку метатегов через конфиг темы.
  • Визуальные конструкторы страниц. Elementor, Divi и подобные drag-and-drop билдеры — то, ради чего многие небольшие бизнесы выбирают WordPress: сайт собирает человек без навыков вёрстки. У Grav страницы редактируются через Markdown-файл или через плагин Admin (веб-панель поверх тех же файлов) — удобно тем, кто пишет в Markdown, но далеко от визуального конструктора для нетехнического заказчика.
  • Мультиавторство и роли. WordPress из коробки поддерживает авторов, редакторов, подписчиков с гибкой системой прав. У Grav есть плагин Login с ролями, но экосистема готовых сценариев (членство, платный контент, форумы вроде bbPress) заметно тоньше.
  • Поиск по сайту. Штатный поиск WordPress упирается в тот же MySQL и часто дополняется отдельным плагином. У Grav поиск по умолчанию — файловый плагин, сканирующий содержимое страниц; для сотен страниц этого достаточно, для тысяч скорость и релевантность заметно уступают индексированному поиску в СУБД.

Итог по этому разделу простой: если ваш сайт нуждается хотя бы в одной из этих вещей на серьёзном уровне — магазине, активном сообществе с комментариями, визуальном конструкторе для нетехнического человека в команде — Grav не заменит WordPress, а заставит либо урезать требования, либо собирать недостающее руками из более скромного набора компонентов.

Установка Grav на VPS

Grav не требует MySQL или MariaDB — только PHP с типовым набором расширений (curl, mbstring, gd и подобные, актуальный список — в системных требованиях на сайте проекта на момент установки) и веб-сервер. Быстрый старт через встроенный скачиваемый архив:

cd /var/www
wget https://getgrav.org/download/core/grav-admin/latest -O grav.zip
unzip grav.zip
mv grav-admin site
chown -R www-data:www-data site

Архив grav-admin уже включает плагин Admin — веб-панель для редактирования контента без прямого доступа к файлам по SSH. Конфигурация nginx похожа на обычный PHP-сайт, но с точечными правилами для служебных файлов, которые Grav просит не отдавать наружу напрямую:

server {
    listen 80;
    server_name example.com;
    root /var/www/site;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    location ~ /(\.git|cache|bin|logs|backup|webserver-configs)/ {
        deny all;
    }
}

После первого запуска в браузере мастер настройки создаёт учётку администратора для панели Admin. Дальше — bin/gpm install <тема> для темы и bin/gpm install <плагин> для расширений. Если контент редактируется через веб-панель Admin, процессу PHP-FPM (обычно www-data) нужно право писать в user/pages/, user/data/ и cache/ — без этого сохранение из браузера падает с ошибкой доступа. Если же вы редактируете Markdown-файлы напрямую по SSH или через git-деплой без Admin-плагина, PHP-FPM вообще не нуждается в правах на запись в контентные папки — конфигурация чуть безопаснее.

Кому что подходит: таблица решения

КритерийWordPressGrav
Хранение контентаMySQL/MariaDB, таблицыMarkdown-файлы, YAML frontmatter
Бэкапдамп БД + архив файлов, оба должны совпасть по времениархив одной директории, файлы всегда согласованы
Перенос на новый доменнужен search-replace абсолютных URL в БДобычно не нужен, ссылки строятся из структуры страниц
Версионирование контента через gitтребует плагинов, неестественно для БДнативно, контент — обычные файлы
Нужен MySQL/MariaDB на сервереда, отдельный процесс и его тюнингнет
Каталог плагинов и темдесятки тысяч записейсотни записей
Интернет-магазинWooCommerce, зрелая экосистеманет сопоставимого готового решения
Комментарии из коробкиданет, нужен сторонний виджет
Визуальный конструктор страницElementor и подобныенет, редактирование Markdown или через Admin-панель
Производительность на простом сайте без тюнинганужен кэш поверх БД для скоростибыстро за счёт отсутствия похода в БД
Поиск на тысячах странициндексированный поиск в СУБД (штатный или с плагином)файловый поиск, медленнее на больших объёмах
Порог входа для нетехнического редакторанизкий (визуальный редактор)выше без Admin-плагина, средний с ним

Если вы делаете блог, документацию, портфолио или лендинг без магазина, форума и комментариев из коробки — Grav даёт реальный выигрыш в простоте эксплуатации: один процесс вместо LEMP-стека, бэкап одной командой, версионирование контента через git без плагинов. Если на сайте нужна хотя бы одна вещь из большой экосистемы WordPress — магазин, активное комьюнити, визуальный конструктор для коллег без навыков вёрстки — время, сэкономленное на бэкапах, вы потратите на самостоятельную разработку недостающей функциональности. Классический стек для WordPress разбирали в статье про пошаговую установку WordPress на LEMP.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать VPS под сайт

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Можно ли перенести существующий сайт с WordPress на Grav автоматически?

Готового универсального конвертера, который перенесёт весь контент без ручной проверки, нет. Есть отдельные скрипты и плагины сообщества для выгрузки постов WordPress в Markdown, но верстку, метаданные и структуру меню обычно приходится проверять и донастраивать руками — это не однокнопочная миграция.

Нужен ли на сервере MySQL, если параллельно с Grav крутится другой сайт на WordPress?

Нет, MySQL нужен только для того сайта, который его использует. Grav-сайт можно разместить на том же VPS без единой связи с базой данных — они просто независимые процессы под одним веб-сервером с разными server блоками в nginx.

Что будет, если файлов на диске станет очень много — тысячи страниц?

Файловая система и кэш Grav справляются, но операции вроде полного пересканирования дерева страниц (переиндексация после массового изменения) на тысячах файлов заметно медленнее, чем индексированный запрос к таблице в MySQL. Для очень крупных каталогов (тысячи и десятки тысяч записей) реляционная модель WordPress архитектурно выигрывает.

Безопаснее ли Grav, потому что нет базы данных?

Отсутствие MySQL убирает целый класс атак — SQL-инъекции просто некуда вставлять. Но остаются уязвимости PHP-кода, плагинов, прав доступа к файлам и самого веб-сервера — Grav не застрахован от взлома в принципе, просто вектор атаки сужается. С WordPress, где заражения через уязвимые плагины — частая причина, разбор конкретных случаев есть в статье WordPress: сайт взломали, причины и решение — часть этих сценариев (уязвимый плагин с SQL-инъекцией) для Grav просто неприменима, а часть (веб-шелл через уязвимость в коде) актуальна для обеих систем.

Можно ли использовать Grav как headless CMS, отдавая контент через API во внешний фронтенд?

Да, у Grav есть встроенный REST API (через плагин или ядро, в зависимости от версии) для отдачи содержимого страниц в формате JSON — это рабочий сценарий, если фронтенд собран отдельно (React, Vue) и нужен только источник контента без собственного рендеринга HTML.

Что проще администрировать на VPS с ограниченной памятью — Grav или WordPress?

Grav обычно легче по требованиям к оперативной памяти, потому что не нужен процесс MySQL, который на минимальных VPS (1 ГБ RAM) сам по себе съедает заметную долю ресурсов и требует тонкой настройки. Для сайтов на слабом сервере это ощутимый практический плюс.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →