MAATRIX / Блог / PostHog на Ubuntu 24.04: пошаговая установка

PostHog на Ubuntu 24.04: пошаговая установка

MAATRIX

Google Analytics покажет, откуда пришёл пользователь, но не ответит, почему он бросил корзину на третьем шаге оформления заказа. Для продуктовой аналитики — воронок, записей сессий, когорт и feature flags — нужен отдельный инструмент, и обычно это подписка на Amplitude или Mixpanel от пары сотен долларов в месяц. PostHog даёт всё то же самое как self-hosted open-source платформу: разворачиваете один раз на своём VPS и дальше платите только за сервер. Ниже — рабочая пошаговая установка на чистом Ubuntu 24.04 через Docker Compose, с доменом, HTTPS и первым проектом в дашборде.

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

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

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

Что такое PostHog и когда self-hosted оправдан

PostHog — open-source платформа продуктовой аналитики: воронки (funnels), анализ путей пользователя (path analysis), записи сессий (session replay), когорты, A/B-тесты и feature flags в одном интерфейсе. SDK есть для JavaScript, iOS, Android, Python, Node.js, Go, Ruby — события летят в PostHog так же, как раньше летели бы в Google Analytics или Amplitude, только код и хранение остаются у вас.

У проекта есть облачная версия (PostHog Cloud, US/EU), она удобна, если не хочется администрировать инфраструктуру, но тарификация построена на количестве событий и быстро становится ощутимой на продукте с активной аудиторией. Self-hosted вариант снимает этот лимит: цена не зависит от числа событий, вы платите только за ресурсы сервера. Отдельный плюс для проектов, ориентированных на Россию или Европу — данные о пользователях не покидают вашу инфраструктуру, что упрощает разговор о GDPR и 152-ФЗ.

Обратная сторона — под капотом self-hosted PostHog это не один контейнер, а связка из ClickHouse (хранилище событий), PostgreSQL (метаданные, пользователи, настройки), Redis (очереди и кэш), Kafka или его облегчённая замена (шина сообщений между веб-слоем и воркерами) плюс сами веб- и worker-контейнеры PostHog. Это не Plausible и не Umami с двумя сервисами — стек тяжелее, и об этом нужно знать до того, как арендовать сервер.

Требования к серверу и подготовка Ubuntu 24.04

Официальный «hobby»-сценарий развёртывания PostHog (для одного сервера, без Kubernetes) рассчитан на нагрузку небольшого-среднего проекта. Ориентировочно закладывайте:

ПараметрМинимумКомфортно
vCPU46-8
RAM8 ГБ16 ГБ
Диск60 ГБ SSD100+ ГБ SSD
ОСUbuntu 24.04 LTSUbuntu 24.04 LTS

Это ориентир, не измеренный бенчмарк: ClickHouse и Kafka быстро съедают память под кэши и буферы, и на 4 ГБ RAM стек либо не поднимется, либо будет падать под нагрузкой. Если планируете десятки тысяч событий в день и запись сессий (она самая тяжёлая по трафику и диску), закладывайте RAM и диск с запасом — session replay хранит видео-подобные снапшоты DOM, а не просто строки в базе.

Подготовьте систему:

sudo apt update && sudo apt upgrade -y
sudo apt install -y curl git ca-certificates gnupg ufw
sudo timedatectl set-timezone UTC

Понадобится домен или поддомен (например, analytics.example.com) с A-записью на IP сервера — без него не получить бесплатный SSL-сертификат для дашборда. Если домен ещё не настроен, шаги DNS и привязки описаны в статье про настройку домена и DNS на Ubuntu 24.04.

Откройте нужные порты в firewall:

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

Если раньше не работали с ufw — подробный разбор правил и типичных ошибок есть в статье про настройку firewall UFW на Ubuntu 24.04.

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

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

Арендовать сервер

Установка Docker и Docker Compose

PostHog self-hosted разворачивается контейнерами, поэтому сначала ставим Docker Engine с официального репозитория (версия из apt в Ubuntu часто устаревшая и без нужного плагина compose):

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Добавьте своего пользователя в группу docker, чтобы не набирать sudo перед каждой командой, и перелогиньтесь:

sudo usermod -aG docker $USER
newgrp docker
docker compose version

Последняя команда должна вывести версию плагина — если её нет, установка прошла с ошибкой и повторять дальнейшие шаги смысла нет.

Развёртывание PostHog через Docker Compose

Официальный путь для одного сервера — клонировать репозиторий PostHog и поднять готовый docker-compose.yml, который описывает весь стек (веб, worker, ClickHouse, Postgres, Redis, Kafka/очередь, плюс Caddy для автоматического HTTPS):

git clone https://github.com/PostHog/posthog.git
cd posthog

В репозитории на момент установки может быть отдельный скрипт для «hobby»-развёртывания (обычно в каталоге bin/) — он сам генерирует .env с случайными секретами и паролями и запускает docker compose up. Точное имя скрипта и структура репозитория со временем меняются, поэтому перед запуском откройте README.md в клонированном репозитории и сверьтесь с актуальной инструкцией — команда PostHog регулярно обновляет процесс установки, и слепо копировать чужую команду двухлетней давности рискованно.

Если используете .env-файл вручную, минимально нужно задать:

DOMAIN=analytics.example.com
POSTHOG_SECRET_KEY=$(openssl rand -hex 32)

DOMAIN — это адрес, по которому будет открываться дашборд; входящий в стек Caddy сам выпустит для него Let's Encrypt-сертификат при первом запуске, если DNS уже указывает на сервер. Секретный ключ обязателен — без него PostHog не поднимется, а генерировать его вручную через openssl rand надёжнее, чем оставлять дефолтное значение из примера.

Запуск:

docker compose up -d

Первый старт — самый долгий шаг: контейнеры тянут образы, ClickHouse и Postgres накатывают миграции, Kafka создаёт топики. Реальное время зависит от скорости диска и канала сервера, поэтому ориентируйтесь не на секунды, а на прогресс в логах:

docker compose logs -f web

Дождитесь строки о том, что веб-сервер слушает порт, и проверьте статус контейнеров:

docker compose ps

Все сервисы должны быть в состоянии running (или healthy, если у контейнера настроен healthcheck) — если что-то в restarting, смотрите логи именно этого контейнера: docker compose logs <имя-сервиса>.

Первый запуск: домен, HTTPS и создание проекта

Откройте https://analytics.example.com в браузере — если DNS и порты настроены верно, Caddy из состава стека уже выдал валидный сертификат, и браузер не покажет предупреждения. Первая загрузка страницы регистрации может занять несколько секунд, пока PostHog дозагружает статику из контейнера.

При первом заходе PostHog предложит создать аккаунт администратора (email и пароль) и организацию. После входа система сразу создаёт первый проект и показывает Project API Key — его нужно вставить в SDK на сайте или в приложении. Базовый вариант для веба — сниппет в <head>:

<script>
  !function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){...})
  (document,window.posthog||[]);
  posthog.init('ВАШ_PROJECT_API_KEY', { api_host: 'https://analytics.example.com' })
</script>

Актуальный полный сниппет и SDK для конкретного языка PostHog показывает прямо в интерфейсе на странице настроек проекта — копировать код лучше оттуда, а не из старых гайдов: он периодически обновляется вместе с версией библиотеки.

После того как события начали поступать (обычно видно в разделе Activity через одну-две минуты после первого клика на сайте), можно собирать первую воронку: Product Analytics → Insights → New Insight → Funnel, задать 2-3 шага (например, «зашёл на сайт» → «добавил в корзину» → «оформил заказ») — и сразу увидеть, на каком шаге теряются пользователи.

Feature flags и запись сессий

Отдельная причина ставить именно PostHog, а не классическую аналитику — feature flags встроены в тот же продукт, без отдельного сервиса вроде LaunchDarkly. Создаются в разделе Feature Flags: задаёте ключ флага, условия показа (например, только 20% пользователей или конкретный email-домен) и в коде проверяете:

if (posthog.isFeatureEnabled('new-checkout-flow')) {
  // показать новый флоу оформления заказа
}

Флаг можно включить или выключить мгновенно из дашборда без деплоя — полезно для постепенного раската фичи или быстрого отката, если что-то пошло не так.

Session replay (запись сессий) включается отдельным переключателем в настройках проекта и требует явного согласия — по умолчанию PostHog не пишет содержимое полей ввода и маскирует чувствительные данные, но стоит явно проверить настройки маскирования перед включением на продакшене, особенно если через формы проходят платёжные данные или пароли. Учтите: это самая ресурсоёмкая функция стека — каждая записанная сессия занимает заметно больше места, чем обычные события, так что включайте её выборочно (например, только для сессий с ошибками) и следите за ростом диска под ClickHouse.

Обслуживание: бэкапы, обновления, мониторинг

Self-hosted PostHog — это ваша ответственность за резервные копии и обновления, в отличие от облачной версии. Минимальный план:

  • Бэкап Postgres (пользователи, настройки, дашборды):
  docker compose exec postgres pg_dumpall -U posthog > posthog_pg_$(date +%F).sql
  • Бэкап ClickHouse (события) — данных обычно на порядки больше, чем в Postgres, поэтому для регулярных копий разумнее использовать clickhouse-backup или снапшоты тома, а не построчный дамп на живом инстансе.
  • Копии выносите за пределы сервера — на S3-совместимое хранилище или отдельный сервер бэкапов. Общие принципы организации бэкапов на VPS разобраны в статье про бэкап и восстановление с BorgBackup, подход применим и здесь, просто добавьте в список каталогов тома ClickHouse и Postgres.

Обновление стека:

cd posthog
git pull
docker compose pull
docker compose up -d

Перед обновлением на мажорную версию обязательно прочитайте changelog в репозитории — миграции ClickHouse иногда требуют дополнительных шагов, и накатывать их вслепую на продакшен без свежего бэкапа не стоит.

За ресурсами стоит следить постоянно: ClickHouse и Kafka под нагрузкой могут упереться в память раньше, чем вы это заметите по логам. Если на сервере уже развёрнут Prometheus, вынесение метрик Docker-хостов в общий дашборд описано в статье про Grafana и Prometheus на Ubuntu 24.04 — полезно повесить алерт на свободную память и место на диске именно для этого сервера, стек PostHog не прощает нехватки ресурсов тихо, он начинает ронять отдельные контейнеры.

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

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

Арендовать сервер

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

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

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

Хватит ли 4 ГБ RAM для PostHog self-hosted?

Формально стек может запуститься, но ClickHouse и Kafka быстро упрутся в память уже на небольшом трафике, а session replay добьёт диск. Для стабильной работы закладывайте от 8 ГБ, для продакшена с записью сессий — 16 ГБ и выше.

Чем self-hosted PostHog отличается от облачного PostHog Cloud?

Функционал в целом тот же, разница в том, кто администрирует инфраструктуру и как считается цена: у Cloud — по числу событий подпиской, у self-hosted — по ресурсам сервера, без верхнего лимита событий.

Можно ли поставить PostHog без Kafka, чтобы упростить стек?

У проекта есть более лёгкие сценарии развёртывания для небольших нагрузок, но конкретный состав компонентов меняется от версии к версии — перед установкой сверьтесь с актуальным docker-compose.yml и README в репозитории, а не с гайдами многолетней давности.

Нужен ли отдельный домен именно под аналитику?

Не обязательно, но удобнее: поддомен вроде analytics.example.com проще защитить отдельным SSL и ограничить доступ на уровне DNS или firewall, не трогая основной сайт.

Что делать, если контейнер web не поднимается после docker compose up?

Сначала смотрите docker compose logs web — почти всегда причина в отсутствующем POSTHOG_SECRET_KEY, недоступном Postgres (ещё не прошли миграции) или неверном DOMAIN в .env. Дайте связке ClickHouse+Postgres полностью подняться перед тем, как считать веб-контейнер сломанным.

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

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

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