Выбор системы веб-аналитики для самостоятельного хостинга
Сравнение Plausible, Umami, Matomo, GoatCounter и GoAccess для VPS. Узнайте, как объем RAM, выбор базы данных и настройка reverse proxy влияют на работу вашего сервера.
Какой инструмент веб-аналитики с самостоятельным хостингом выбрать для VPS?
Инструменты веб-аналитики с самостоятельным хостингом делятся на два типа, и выбор неверного типа обойдётся вам дороже, чем выбор неудачного продукта. Первый тип запускает небольшой скрипт в браузере посетителя и сохраняет данные, которые этот скрипт передаёт. Второй тип считывает access log, который ваш веб-сервер уже создаёт. Всё остальное, включая базу данных и необходимый объём оперативной памяти, зависит именно от этого выбора.
Краткий ответ для небольшого сервера. GoatCounter и Medama помещаются в 1 GB RAM, так как каждый из них представляет собой один процесс, работающий с одним файлом. Umami добавляет контейнер с Postgres и предоставляет панель управления, понятную нетехническому специалисту. Plausible Community Edition и Rybbit используют ClickHouse, поэтому планируйте 2 GB RAM или больше. Matomo — это полнофункциональный продукт, требующий сервер, соответствующий объёму вашего трафика. GoAccess вообще не добавляет ничего на страницу, так как он считывает уже существующий лог-файл.
Тег скрипта или серверный лог: что видит каждый из них
Тег скрипта отслеживает браузеры. Страница загружается, скрипт выполняется и отправляет один запрос вашему сборщику данных. Всё, что разрывает эту цепочку, остаётся для вас невидимым: отключённый JavaScript, фильтр, блокирующий запрос, сбой при отправке запроса к сборщику или поисковый робот, который не выполняет скрипты.
Парсер логов отслеживает запросы. Ваш веб-сервер записывает одну строку на каждый запрос независимо от того, установили ли вы что-либо, поэтому данные уже находятся на диске. Он видит каждого робота и каждое обращение к файлу, в котором нет тега скрипта. Он не может видеть, что происходило внутри браузера, и не может увидеть страницу, загруженную из кэша браузера или с CDN (content delivery network), стоящей перед вашим сервером, так как этот запрос не дошёл до вашего сервера.
Эти два числа не совпадут, и ни одно из них не является неверным. Matomo поддерживает оба метода и документирует, что именно теряется при импорте логов по сравнению с JavaScript-трекером: разрешение экрана, заголовки страниц, события, отслеживание контента, тепловые карты, записи сессий и аналитика форм. Этот список — цена подсчёта запросов вместо браузеров.
Трафик ботов — вторая причина разрыва в данных. Подсчёт на основе логов включает поисковых роботов, если вы их не отфильтруете, а на обычном сайте доля роботов достаточно велика, чтобы изменить ваши выводы. GoAccess и импорт логов в Matomo фильтруют известных ботов. Ни один из них не может отфильтровать робота, который подделывает свой user agent, что является веской причиной сочетать любой подсчёт на основе логов с блокировкой AI-роботов на уровне сервера и анализировать лог уже после применения блокировки, а не до неё.
GoAccess: аналитика на основе имеющихся логов
Установите GoAccess из официального репозитория проекта для Debian и Ubuntu, так как версии в системных репозиториях часто отстают от актуальных релизов.
wget -O - https://deb.goaccess.io/gnugpg.key | gpg --dearmor | sudo tee /usr/share/keyrings/goaccess.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/goaccess.gpg arch=$(dpkg --print-architecture)] https://deb.goaccess.io/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/goaccess.list
sudo apt-get update
sudo apt-get install goaccessЗатем укажите путь к лог-файлу и создайте статический отчет.
goaccess /var/log/nginx/access.log -o ~/report.html --log-format=COMBINEDЭта команда завершится ошибкой Permission denied для обычного пользователя, так как в Ubuntu владельцем логов nginx является root, а группа — adm. Добавьте себя в эту группу с помощью sudo usermod -aG adm $USER, затем завершите сеанс и войдите снова, так как членство в группах считывается при входе в систему. Выполните id и убедитесь, что adm присутствует в списке, прежде чем пробовать снова.
Отчет по текущему логу охватывает только те данные, которые еще не были перемещены утилитой logrotate. Запросы за вчерашний день находятся в access.log.1, а более старые записи сжаты, поэтому для формирования еженедельного отчета необходимо считывать и ротированные файлы.
zcat /var/log/nginx/access.log.*.gz | goaccess - --log-format=COMBINED -o ~/last-week.htmlТакже существует интерактивный режим --real-time-html, который обновляет страницу через WebSocket. Для него требуется отдельный порт и собственное правило проксирования. Для большинства сайтов достаточно ежечасного отчета, создаваемого через cron: это проще в настройке и безопаснее.
GoatCounter: один бинарный файл на Go и один файл SQLite
GoatCounter поставляется в виде статически скомпилированного бинарного файла, поэтому устанавливать среду выполнения не требуется. Загрузите сборку со страницы releases и запустите её или используйте образ.
docker run -p 8080:8080 -v goatcounter-data:/home/goatcounter/goatcounter-data arp242/goatcounterПри запуске в виде бинарного файла goatcounter serve ожидает подключений на порту 8080 и создает базу данных SQLite по пути ./goatcounter-data/db.sqlite3. Создайте первый сайт через командную строку, а не через веб-мастер, если экземпляр уже находится за прокси-сервером.
goatcounter db create site -vhost=stats.example.com -user.email=me@example.comПриложение может самостоятельно управлять сертификатами с помощью goatcounter serve -listen=:443 -tls=tls,rdr,acme, используя ACME (автоматизированную среду управления сертификатами), что удобно для сервера, на котором не запущено ничего другого. Если порт 443 уже занят Nginx или Caddy, оставьте GoatCounter на порту 8080 и настройте проксирование на него. Размер скрипта отслеживания составляет около 3.5K, согласно данным проекта; также доступен трекинг-пиксель для страниц без JavaScript. Если на высоконагруженном сайте производительность SQLite становится ограничением, тот же бинарный файл поддерживает работу с Postgres через goatcounter serve -db 'postgresql+dbname=goatcounter'. Резервное копирование выполняется простым копированием файла, что является главным преимуществом такой архитектуры инструмента.
Medama: один контейнер, которому требуется 256 МБ
Medama — это новейший вариант в виде одного бинарного файла. По своей архитектуре он не использует cookie, а разработчики заявляют о размере трекера менее 1 КБ и возможности работы на виртуальных машинах с 256 МБ оперативной памяти. Это официальные заявления проекта, а не результаты измерений для данного руководства.
docker volume create medama-data
docker run -d -p 127.0.0.1:8080:8080 -v medama-data:/app/data ghcr.io/medama-io/medama:latestОфициальная команда публикует порт как 8080:8080. Префикс loopback в команде выше добавлен намеренно, и в разделе про reverse proxy объясняется почему. Первичный вход выполняется под учетной записью admin с паролем CHANGE_ME_ON_FIRST_LOGIN; название этого пароля и является инструкцией.
Существует один задокументированный сценарий сбоя, с которым вы можете столкнуться. Вход в систему работает только по HTTPS или через localhost, поэтому, если вы настроите прокси до получения сертификата, форма будет отклонять верный пароль без вывода сообщения об ошибке. Сначала завершите настройку TLS (transport layer security), а затем выполняйте вход.
Umami: Postgres и привычная панель управления
git clone https://github.com/umami-software/umami.git
cd umami
docker compose up -dЭта команда запускает приложение на порту 3000 вместе с контейнером PostgreSQL. Согласно документации, минимально требуемая версия PostgreSQL — 12.14, а для сборки из исходного кода необходима версия Node.js 18.18 или новее. Существует готовый образ docker.umami.is/umami-software/umami:postgresql-latest, которому требуется DATABASE_URL, указывающий на уже запущенную базу данных.
Первичные данные для входа — admin с паролем umami. Смените их до того, как направите DNS на сервер, так как экземпляр станет доступен из Интернета сразу после обновления записи и ответа прокси-сервера. Подробности о Compose, файлах окружения и политике перезапуска см. в разделе стек Docker Compose на VPS, вместо того чтобы копировать стек, который вы не изучили.
Ресурсоемкость составляет один процесс Node и базу данных Postgres. Это тяжелее, чем одиночный бинарный файл, но значительно легче любого решения на базе ClickHouse.
Plausible Community Edition: ClickHouse задает минимальный объем RAM
git clone -b v3.2.1 --single-branch https://github.com/plausible/community-edition plausible-ce
cd plausible-ce
touch .env
echo "BASE_URL=https://stats.example.com" >> .env
echo "SECRET_KEY_BASE=$(openssl rand -base64 48)" >> .env
docker compose up -dВерсия v3.2.1 является актуальной на август 2026 года, и команда клонирования фиксирует её намеренно. Стек состоит из трех частей: приложения, Postgres для учетных записей и настроек, а также ClickHouse для данных о событиях. SECRET_KEY_BASE должен быть строкой длиной не менее 64 байт, что и генерирует вызов openssl.
Собственные требования Plausible предполагают наличие не менее 2 GB RAM, чтобы ClickHouse и приложение не были завершены механизмом out of memory killer, а также процессор с поддержкой SSE 4.2 или NEON, которые необходимы для ClickHouse. Второе требование стоит проверить перед покупкой, так как это одно из практических различий при выборе между ARM и x86 VPS. ClickHouse также будет использовать столько памяти, сколько посчитает доступным, поэтому на общем сервере установите ограничение, как описано в ограничении памяти контейнера в Compose.
BASE_URL должен в точности соответствовать публичному URL. Если это не так, вы входите в систему, приложение перенаправляет на неверный хост, а session cookie записывается для домена, на котором ваш браузер не находится, поэтому вы возвращаетесь на форму входа без сообщения об ошибке.
Поставляемый файл compose не публикует порт, так как предполагается наличие прокси перед ним. Добавьте переопределение, которое публикует стандартный порт приложения только на loopback.
cat > compose.override.yml << EOF
services:
plausible:
ports:
- 127.0.0.1:8000:8000
EOFMatomo: полноценный продукт и требования к серверу
Matomo работает на PHP с использованием MySQL или MariaDB, что относит его к классическому веб-стеку, а не к контейнерному. Это также единственный инструмент в данном списке, для которого опубликованы рекомендации по аппаратному обеспечению в зависимости от объема трафика.
The data behind this chart
[
{
"label": "100K/month",
"cpu_cores": 2,
"ram_gb": 2,
"disk_gb": 50
},
{
"label": "1M/month",
"cpu_cores": 4,
"ram_gb": 8,
"disk_gb": 250
},
{
"label": "10M/month",
"cpu_cores": 8,
"ram_gb": 16,
"disk_gb": 400
}
]Это минимальные требования Matomo по состоянию на август 2026 года, а не результаты измерений, полученные в рамках данного руководства. При посещаемости до 100 000 просмотров страниц в месяц требуется 2 ядра CPU, 2 ГБ оперативной памяти и 50 ГБ SSD; один сервер вмещает как приложение, так и базу данных. На уровне 1M/month объем памяти возрастает до 8 ГБ, а дискового пространства — до 250 ГБ. На уровне 10M/month Matomo рекомендует использовать два сервера, при этом последняя строка показывает требования к серверу базы данных: 16 ГБ оперативной памяти и 400 ГБ дискового пространства. Сравнивайте эти показатели диска с вариантами на основе одного бинарного файла, где весь набор данных хранится в одном файле SQLite.
Архивация — это то, что часто вызывает удивление. По умолчанию Matomo формирует отчеты в момент открытия панели управления пользователем, поэтому по мере роста объема данных панель работает медленнее и в конечном итоге время ожидания ответа истекает. Документированное решение заключается в отключении архивации, запускаемой браузером, в общих настройках и настройке запуска архиватора через cron от имени пользователя, которому принадлежат файлы Matomo, из директории Matomo.
php console core:archive --url=https://analytics.example.comMatomo также хранит таблицы необработанных логов рядом с таблицами обработанных отчетов и может удалять старые необработанные данные и отчеты по расписанию. Включите эту функцию при установке, а не тогда, когда диск будет полностью заполнен. Matomo также может импортировать логи доступа сервера, что делает его единственным продуктом в этом списке, который охватывает оба типа данных одновременно.
Rybbit и новые стеки
git clone https://github.com/rybbit-io/rybbit.git
cd rybbit
chmod +x *.sh
./setup.sh your.domain.nameRybbit — это недавний проект с современной панелью управления. Скрипт установки создает файл окружения и запускает стек с помощью Docker Compose. Он использует ClickHouse и включает Caddy в качестве собственного веб-сервера, который занимает порт 443 и запрашивает сертификат для указанного домена. Если на сервере порт 443 уже занят Nginx, скрипт не сможет выполнить привязку. В этом случае используйте ручной запуск через Compose и разместите проект за уже имеющимся прокси-сервером. Согласно документации, требуется не менее 2 GB оперативной памяти, тестирование проводилось на Ubuntu 24 LTS, а для архитектуры ARM необходима поддержка ARMv8.2-A или новее из-за особенностей ClickHouse.
Важное предостережение для любого молодого проекта: функции добавляются быстро, как и изменения, нарушающие обратную совместимость. Фиксируйте версию (тег), читайте примечания к выпуску перед обновлением и обязательно делайте резервную копию базы данных.
Хранение данных и рост дискового пространства: самостоятельные измерения
Рост объема данных на диске зависит от того, что именно инструмент сохраняет для каждого события. GoatCounter агрегирует посещения в счетчики, поэтому размер файла больше зависит от количества уникальных страниц и дней, чем от общего объема трафика. Umami и Matomo сохраняют отдельные записи для каждого события, а Matomo дополнительно создает таблицы с обработанными отчетами поверх исходных данных. ClickHouse хранит события в столбцах и сильно их сжимает, поэтому Plausible справляется с объемами, которые перегрузили бы строковое хранилище.
В этом руководстве не приводится показатель «мегабайт на миллион просмотров», так как он не был измерен на вашем трафике. Проведите измерения самостоятельно. Измените имена сервисов и пользователей в соответствии с вашим файлом Compose.
du -h goatcounter-data/db.sqlite3
docker compose exec db psql -U umami -d umami -c "SELECT pg_size_pretty(pg_database_size('umami'));"
docker compose exec plausible_events_db clickhouse-client -q "SELECT formatReadableSize(sum(bytes_on_disk)) FROM system.parts WHERE active"Запишите текущее значение, подождите неделю, запишите его снова и разделите разницу на количество просмотров, отображаемое в панели управления за эту неделю. Этот показатель отражает специфику вашего сайта и фильтрацию ботов, поэтому он ценнее любого опубликованного среднего значения. Затем установите лимит хранения данных, пока объем базы остается небольшим. Переполнение диска приводит к остановке всех сервисов на VPS, а не только системы аналитики. Это главный аргумент в пользу того, чтобы размещать том с базой данных там, где df -h сможет прислать вам уведомление. Этот риск требует особого внимания на сервере, где уже хранятся объемные данные, поскольку собственный фотосервер исчерпает место на диске гораздо раньше, чем любая база данных аналитики.
Поведение за обратным прокси на поддомене
Разместите коллектор на поддомене сайта, который он анализирует, например stats.example.com. Это делает запросы к коллектору первосторонними (first-party), поэтому на них не распространяются правила браузеров, блокирующие сторонние запросы.
Привязывайте приложение к loopback при публикации порта контейнера. Docker создает собственные правила firewall до правил ufw, поэтому контейнер, опубликованный как -p 3000:3000, будет доступен из интернета, даже если ufw status сообщает, что порт закрыт. Проверьте это с другого компьютера с помощью curl http://SERVER_IP:3000, и вы увидите дашборд. При публикации как -p 127.0.0.1:3000:3000 тот же тест выдаст Connection refused, и доступ к нему будет только у прокси.
server {
listen 443 ssl;
server_name stats.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Заголовки пересылки (forwarding headers) здесь обязательны. Без X-Forwarded-For каждый визит будет выглядеть как запрос с 127.0.0.1, из-за чего отчет по странам будет пустым, а количество уникальных посетителей сведется к одному. Каждый проект определяет, каким заголовкам и при каких настройках он доверяет, поэтому лучше один раз проверить документацию по прокси, чем делать предположения. Caddy устанавливает эти заголовки автоматически, и Caddyfile для этой задачи состоит всего из двух строк.
stats.example.com {
reverse_proxy 127.0.0.1:3000
}Если вы еще не выбрали прокси, сравнение nginx, Caddy и Traefik поможет понять, какой из них лучше подходит для одного сервера с несколькими поддоменами.
Нужен ли баннер с cookies при self-hosting?
Self-hosting меняет владельца данных, но не меняет требования законодательства к этим данным. Разделяйте два правила. Правило ePrivacy о согласии касается хранения или считывания любой информации на устройстве посетителя, поэтому инструмент, который не устанавливает cookies и не записывает данные в local storage, выпадает из этого конкретного требования. GDPR касается обработки персональных данных, а IP-адрес считается персональными данными. Поэтому вам по-прежнему нужны законное основание, ограничение срока хранения и готовность ответить на запрос пользователя о том, какие данные о нём у вас хранятся.
Plausible, Umami, GoatCounter и Medama по умолчанию не используют cookies. Методы сбора данных в каждом из них различаются в зависимости от проекта и версии, поэтому изучайте документацию по конфиденциальности конкретного проекта, а не общие обзоры. Matomo включает функции анонимизации IP-адресов и конечную точку для отказа от отслеживания (opt out), которые активируются в панели администратора.
Регуляторы в разных странах приходят к разным выводам. Например, французский регулятор CNIL публикует условия, при которых инструменты измерения аудитории могут быть освобождены от получения согласия. Этот раздел является фактической сводкой, а не юридической консультацией. Для реального сайта с реальными пользователями обратитесь к юристу в вашей юрисдикции.
Важный момент, который часто упускают: access log также содержит персональные данные. GoAccess не добавляет скрипты на страницу, но всё равно обрабатывает IP-адреса, поэтому аналитика на основе логов не автоматически освобождает вас от соблюдения правил.
Блокировщики рекламы и причины снижения ваших показателей
Списки фильтров сопоставляют запросы по имени хоста и шаблону URL. Размещаемый на стороннем сервере продукт для аналитики легко отследить, так как все загружают его с одного и того же известного домена. Перенос сборщика данных на ваш собственный поддомен исключает этот хост из запроса, а обслуживание скрипта по выбранному вами пути скрывает стандартное имя файла. Оба действия меняют параметры, по которым работает список фильтров.
В этой статье не приводится процент блокировок, так как измерения не проводились. Доля посетителей, блокирующих конкретную конфигурацию, зависит от вашей аудитории: разработчики блокируют контент гораздо чаще, чем обычные пользователи. Измерьте разрыв самостоятельно. В течение одной недели подсчитайте количество запросов к HTML-страницам в access log с помощью GoAccess и сравните результат с количеством просмотров страниц, которое показывает ваш скриптовый инструмент. Разница — это заблокированные посещения плюс страницы, загруженные из кэша на вашем сайте.
Ожидайте изменения общих показателей в день перехода с облачного продукта, при этом часть изменений не будет связана с блокировками. Разные продукты по-разному определяют просмотр страницы, учитывают ли они смену маршрута внутри single page application и момент завершения сессии. Сравнивайте тренды по неделям, прежде чем делать выводы о падении трафика.
Что выбрать для конкретного сайта
- Личный сайт или блог с посещаемостью примерно до 50,000 просмотров в месяц: GoatCounter или Medama на VPS с 1 GB RAM, где резервные копии выполняются простым копированием файлов.
- Сайт, на который нельзя добавить скрипт, или аудитория, активно блокирующая трекеры: GoAccess, работающий с логами по расписанию.
- Сайт малого бизнеса, где дашборд просматривает кто-то другой: Umami с контейнером Postgres.
- Сайт, где нужны цели и воронки, на сервере с 2 GB RAM или более: Plausible Community Edition или Rybbit, если вам нужен современный дашборд и вы готовы использовать более молодой проект.
- Множество сайтов, несколько учетных записей пользователей или требование хранить «сырые» данные согласно собственной политике удержания: Matomo, с размером ресурсов согласно опубликованным рекомендациям.
Начинайте с самого простого инструмента, который решает вашу текущую задачу. Переход с GoatCounter на Plausible в будущем потребует лишь смены поддомена и потери части истории. Переход с Matomo на что-либо другое потребует миграции, которая вам не понравится. Если вы еще решаете, что разместить на том же сервере, обзор инструментов для self-hosting подскажет, что можно добавить рядом, а если вам нужно отслеживание запросов на уровне приложения, а не просто подсчет посетителей, то для этой задачи лучше подойдет self-hosted система наблюдаемости.
FAQ
Нужно ли размещать баннер согласия на использование файлов cookie при самостоятельном хостинге аналитики?
Нет, это два разных вопроса. Правило о согласии согласно ePrivacy касается хранения или считывания данных на устройстве посетителя, поэтому инструмент, который не создает cookie и не записывает данные в local storage, не подпадает под это требование. GDPR — это другой регламент, регулирующий обработку персональных данных. IP-адрес является персональными данными, поэтому вам все равно нужны законные основания для обработки и установленные сроки хранения, даже если файлы cookie не используются. Самостоятельный хостинг переносит данные на ваш сервер и делает вас ответственной стороной. Ознакомьтесь с рекомендациями вашего регулятора и проконсультируйтесь с юристом по вашему случаю.
Сколько оперативной памяти требуется для самостоятельного хостинга аналитики на VPS?
Требования зависят от хранилища данных, а не от панели управления. GoatCounter и Medama работают как один процесс с одним файлом, и документация Medama указывает, что для небольших сайтов достаточно машин с 256 MB. Umami требует контейнер Postgres в дополнение к Node приложению. Plausible Community Edition и Rybbit используют ClickHouse, и оба проекта требуют минимум 2 GB. Официальное руководство Matomo рекомендует начинать с 2 ядер CPU и 2 GB оперативной памяти для объема до 100,000 просмотров страниц в месяц.
Почему показатели при самостоятельном хостинге ниже, чем у предыдущего аналитического сервиса?
Есть две причины, и обе они объективны. Списки блокировки (filter lists) блокируют часть запросов к счетчикам, поэтому любой инструмент на основе скриптов теряет эти посещения. Кроме того, продукты используют разные методы подсчета: определение просмотра страницы и момент завершения сессии различаются. Сравните данные за неделю по запросам HTML-страниц из вашего access log с данными за ту же неделю по просмотрам страниц через скрипт. Разница между ними — это заблокированные посещения плюс страницы, загруженные из кэша, измеренные на основе вашего собственного сервера, а не заимствованные из чужих статистических оценок.
Могу ли я запустить Plausible или Rybbit на ARM VPS?
Оба проекта используют ClickHouse, а ClickHouse требует поддержки SSE 4.2 на архитектуре x86 или NEON на ARM. В требованиях Plausible это указано прямо, а документация Rybbit гласит, что для ARM-систем требуется ARMv8.2-A или новее. Современные серверные ядра ARM соответствуют этому требованию, а более старые — нет. Ошибка проявляется в том, что ClickHouse отказывается запускаться из-за ошибки набора инструкций, а не из-за проблем в логах приложения. На маломощных ARM-устройствах инструменты, работающие с одним файлом, позволяют избежать этого вопроса, так как они не используют ClickHouse.
Стоит ли анализировать логи сервера вместо использования скрипта отслеживания?
Используйте парсинг логов, если вы не можете добавить скрипт, если ваша аудитория активно использует блокировщики или если вам нужен подсчет, включающий поисковых роботов. GoAccess читает лог, который ваш сервер уже создает, поэтому он не увеличивает вес страницы и не требует базы данных. При этом вы теряете все данные о событиях внутри браузера и не учитываете страницы, отданные через CDN или из кэша браузера, так как эти запросы не доходят до вашего сервера. Многие сайты используют оба метода, рассматривая их как два разных типа измерений.