bolt Valebyte VPS от $4/мес — NVMe, запуск за 60 секунд.

Получить VPS arrow_forward
eco Начальный Туториал

Langfuse self-hosted: трассировка и стоимость LLM-запросов

calendar_month Sep 19, 2026 schedule 18 мин. чтения visibility 28 просмотров
Langfuse self-hosted: трассировка и стоимость LLM-запросов
info

Нужен сервер для этого гайда? Мы предлагаем выделенные серверы и VPS в 50+ странах с мгновенной настройкой.

Нужен сервер для этого гайда?

Разверните VPS или выделенный сервер за минуты.

Langfuse self-hosted: трассировка и стоимость LLM-запросов на своём VPS

TL;DR

Langfuse self-hosted позволяет собирать трассировки LLM-запросов, видеть задержки, ошибки, токены и реальную стоимость вызовов OpenAI, Anthropic, Google, локальных моделей и собственных API-шлюзов. В этом руководстве вы развернёте Langfuse v3 на Ubuntu VPS через Docker Compose, защитите его HTTPS, подключите хранилища данных и настроите резервное копирование.

  • Langfuse сохраняет цепочки вызовов LLM, промпты, ответы, usage и метаданные пользователя.
  • Для небольших команд достаточно VPS с 4 vCPU, 8 GB RAM и NVMe-диском от 100 GB.
  • Развёртывание использует Docker Engine, PostgreSQL 16, ClickHouse, Redis и Caddy.
  • Секреты хранятся в файле .env, а не внутри исходного кода или Docker Compose.
  • HTTPS выпускается автоматически через Caddy и Let's Encrypt.
  • Для надёжной эксплуатации нужно бэкапить PostgreSQL, ClickHouse, конфигурацию и объектное хранилище.

Что мы настраиваем и зачем

Схема: Что мы настраиваем и зачем
Схема: Что мы настраиваем и зачем

Langfuse — платформа observability для приложений с большими языковыми моделями. Она принимает события из SDK, API или интеграций с LangChain, LlamaIndex, OpenAI SDK и другими библиотеками. После этого в веб-интерфейсе можно увидеть полный путь одного пользовательского запроса: входной промпт, промежуточные шаги RAG-пайплайна, вызовы инструментов, ответ модели, расход токенов, стоимость, длительность и ошибки.

Типичная проблема AI-приложения выглядит так: пользователи жалуются на медленные ответы, счета за API растут, а разработчик видит только обрывочные логи приложения. Обычные логи не связывают запрос пользователя, retrieval из векторной базы, два вызова модели и финальный ответ в одну сущность. Langfuse решает это через trace, span и generation: trace описывает пользовательский сценарий, span — технический этап, generation — конкретный вызов LLM.

Self-hosted Langfuse особенно полезен, когда промпты или ответы содержат коммерческие данные, персональные данные, фрагменты документов клиентов, исходный код либо внутренние знания компании. При самостоятельном развёртывании события остаются в вашей инфраструктуре. Наружу уходят только запросы к тому провайдеру модели, которого вы уже используете: например, OpenAI, Anthropic или облачный endpoint локальной модели.

Что будет работать после настройки

  • Создание проектов, окружений и API-ключей для development, staging и production.
  • Трассировка запросов через Python, TypeScript или OpenTelemetry-совместимые интеграции.
  • Расчёт стоимости запросов по моделям, входным и выходным токенам.
  • Поиск медленных, ошибочных и дорогих запросов.
  • Хранение промптов с версиями и публикация prompt templates.
  • Оценка ответов вручную, через пользовательский feedback или LLM-as-a-judge.
  • Экспорт и анализ данных через PostgreSQL, ClickHouse и API.

Cloud-managed или self-hosted

Критерий Облачный сервис Langfuse self-hosted
Скорость старта Несколько минут, инфраструктура уже готова Обычно 1–3 часа на первый production-инстанс
Контроль над данными Данные хранятся у внешнего оператора Данные находятся в вашей БД и вашем хранилище
Обслуживание Обновления и бэкапы выполняет сервис Обновления, мониторинг и бэкапы выполняете вы
Кастомизация сети Ограничена возможностями SaaS Можно использовать VPN, private network, SSO, reverse proxy
Экономика при росте Зависит от тарифа и объёма событий Предсказуемые расходы на серверы и объектное хранилище

Self-hosted вариант не отменяет требования к защите данных. В Langfuse по умолчанию могут сохраняться входы и выходы моделей, а значит, в них могут оказаться email, телефоны, тексты договоров и другие чувствительные сведения. До подключения production-трафика определите срок хранения событий, исключите из логирования ненужные поля и добавьте маскирование секретов в своём приложении.

Практическое правило: отправляйте в Langfuse достаточно контекста для отладки качества и цены, но не дублируйте туда пароли, access tokens, номера платёжных карт и необработанные документы, если они не нужны для анализа.

Какой VPS-конфиг нужен под эту задачу

Схема: Какой VPS-конфиг нужен под эту задачу
Схема: Какой VPS-конфиг нужен под эту задачу

Langfuse не является одним контейнером. Для нормальной работы нужны как минимум веб-приложение и worker, PostgreSQL для транзакционных данных, ClickHouse для аналитических событий и Redis для очередей и кэша. На одном VPS это удобно для небольшой команды и умеренного объёма трассировок, но ресурсы нужно закладывать с запасом.

Нагрузка vCPU RAM NVMe-диск Подходящий сценарий
Минимальный стенд 2 vCPU 4 GB 60 GB Личное тестирование, до нескольких тысяч событий в день
Рабочий минимум 4 vCPU 8 GB 100 GB Небольшая команда, RAG или SaaS с десятками тысяч событий в день
Интенсивная эксплуатация 8 vCPU 16–32 GB 250 GB+ Высокий поток трассировок, длинные промпты, несколько проектов

Практичная стартовая конфигурация — 4 vCPU, 8 GB RAM, 100–160 GB NVMe и канал от 100 Мбит/с. Такой сервер оставляет запас для PostgreSQL и ClickHouse, которые чувствительны к нехватке памяти и медленному диску. В качестве одного из вариантов можно взять VPS с указанными характеристиками, но важнее проверить тип диска, доступность резервных копий и локацию сервера.

Почему NVMe важнее большого HDD

PostgreSQL постоянно пишет журналы транзакций, а ClickHouse создаёт и сливает части таблиц. На HDD интерфейс Langfuse может оставаться доступным, но аналитические запросы, ingestion событий и бэкапы будут заметно медленнее. Для production-инстанса используйте SSD или NVMe. Начните с 100 GB, если храните трассировки 30 дней; при хранении шести месяцев, больших payload и тысячах запросов в час потребуется существенно больше.

Когда нужен dedicated, а не VPS

Выделенный сервер становится оправданным, если вы стабильно принимаете сотни тысяч или миллионы observation-событий в сутки, храните длинные цепочки агентов, запускаете тяжёлые аналитические запросы либо должны изолировать ресурсы базы от соседних виртуальных машин. Ещё один повод — необходимость в 64 GB RAM и нескольких быстрых NVMe-дисках. До этого момента проще масштабировать VPS: увеличить CPU, память и вынести ClickHouse или PostgreSQL на отдельный сервер.

Выбор локации

Локация влияет на задержку между вашим приложением и Langfuse, юридические требования и стоимость межрегионального трафика. Если backend приложения работает в европейском дата-центре, размещайте Langfuse в том же регионе: трассировка будет добавлять миллисекунды, а не десятки миллисекунд. Если в событиях присутствуют данные европейских пользователей, проверьте требования GDPR, DPA и внутренние правила хранения данных.

Подготовка сервера

Схема: Подготовка сервера
Схема: Подготовка сервера

Ниже предполагается чистый сервер с Ubuntu 24.04 LTS, публичным IPv4-адресом и доменом, например langfuse.example.com. Для Ubuntu 22.04 команды почти идентичны. Выполняйте первоначальную настройку через консоль провайдера или SSH под пользователем root, затем отключите постоянную работу под root.

Создание администратора и SSH-доступа

На локальном компьютере создайте ключ, если его ещё нет. Используйте современный алгоритм Ed25519 и защитите ключ парольной фразой.

ssh-keygen -t ed25519 -a 100 -C "admin@langfuse"

Скопируйте публичный ключ на сервер и войдите под root. Замените IP-адрес на адрес VPS.

ssh-copy-id [email protected]
ssh [email protected]

Создайте отдельного пользователя, добавьте его в группу sudo и подготовьте каталог SSH.

adduser deploy
usermod -aG sudo deploy
install -d -m 700 -o deploy -g deploy /home/deploy/.ssh
cp /root/.ssh/authorized_keys /home/deploy/.ssh/authorized_keys
chown deploy:deploy /home/deploy/.ssh/authorized_keys
chmod 600 /home/deploy/.ssh/authorized_keys

Откройте вторую SSH-сессию и убедитесь, что пользователь входит с ключом. Не закрывайте root-сессию, пока проверка не завершится.

ssh [email protected]
sudo whoami

Обновление системы и базовые инструменты

Обновите пакеты до актуального состояния. После обновления ядра перезагрузите сервер в удобное время.

sudo apt update && sudo apt full-upgrade -y
sudo apt install -y ca-certificates curl gnupg ufw fail2ban unattended-upgrades \
  jq vim htop cron rsync

Проверьте, требуется ли перезагрузка.

test -f /var/run/reboot-required && echo "Reboot required"
sudo reboot

Firewall и Fail2ban

На сервере должны быть доступны SSH, HTTP и HTTPS. Не публикуйте наружу PostgreSQL, Redis или ClickHouse: они будут доступны только контейнерам во внутренней Docker-сети.

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

Fail2ban ограничит перебор SSH-паролей и вредоносные повторные подключения. Создайте локальную конфигурацию, не редактируя файл пакета напрямую.

sudo tee /etc/fail2ban/jail.d/sshd.local > /dev/null <<'EOF'
[sshd]
enabled = true
maxretry = 5
findtime = 10m
bantime = 1h
EOF

sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd

После подтверждения входа ключом отключите вход root и аутентификацию паролем. Это снижает поверхность атаки, но сначала обязательно убедитесь, что ваш SSH-ключ работает.

sudo tee /etc/ssh/sshd_config.d/99-hardening.conf > /dev/null <<'EOF'
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
X11Forwarding no
EOF

sudo sshd -t && sudo systemctl reload ssh

Также включите автоматическую установку security-обновлений. Docker-образы всё равно потребуется обновлять отдельно, но уязвимости базовой ОС будут закрываться без ручного вмешательства.

sudo dpkg-reconfigure --priority=low unattended-upgrades

Установка ПО — пошагово

Схема: Установка ПО — пошагово
Схема: Установка ПО — пошагово

В этой схеме используется Docker Engine 28.x или новее, Docker Compose v2, Langfuse ветки v3, PostgreSQL 16, ClickHouse 24.8 LTS и Redis 7.2. Версии контейнеров следует фиксировать перед production-обновлением: тег latest может привести к неожиданной миграции схемы или несовместимости.

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

Добавьте официальный репозиторий Docker для Ubuntu. Команда устанавливает Docker Engine, CLI, Buildx и Compose plugin.

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

Разрешите пользователю deploy запускать Docker без sudo. Членство в группе Docker фактически даёт административные возможности на сервере, поэтому добавляйте туда только доверенных пользователей.

sudo usermod -aG docker deploy
newgrp docker
docker version
docker compose version

Создание рабочей директории

Храните Compose-файл, переменные окружения, Caddyfile и скрипты рядом, в каталоге, доступном пользователю развёртывания. Данные баз будут находиться в Docker volumes.

sudo install -d -m 750 -o deploy -g deploy /opt/langfuse
cd /opt/langfuse
mkdir -p caddy backup scripts
touch .env
chmod 600 .env

Генерация криптографических секретов

Langfuse использует отдельные секреты для сессий, соли и шифрования. Не используйте короткие примеры из документации и не повторяйте один секрет для всех переменных.

openssl rand -base64 48
openssl rand -hex 32
openssl rand -base64 48
openssl rand -base64 32

Сохраните четыре результата: они понадобятся в .env. Для паролей PostgreSQL, Redis и ClickHouse создайте отдельные случайные строки.

openssl rand -base64 32
openssl rand -base64 32
openssl rand -base64 32

Проверка домена до запуска

Создайте DNS-запись типа A для langfuse.example.com, направив её на публичный IPv4 сервера. Caddy сможет получить сертификат только если порт 80 доступен из интернета, а DNS уже указывает на этот сервер.

dig +short A langfuse.example.com
curl -4 ifconfig.me

Оба адреса должны совпасть. Если используется Cloudflare или другой прокси-DNS, на первом запуске проще временно отключить proxy-режим либо убедиться, что HTTP challenge не блокируется.

Получение образов и стартовая диагностика

После создания конфигурации из следующего раздела Docker загрузит нужные образы. Эта команда предварительно скачивает их и позволяет увидеть ошибки сети или доступа к registry до запуска.

cd /opt/langfuse
docker compose pull
docker compose config > /tmp/langfuse-rendered-compose.yml
docker compose config --quiet

Конфигурация Langfuse, HTTPS и проверка

Ниже приведена компактная single-node конфигурация. Она подходит для начала работы и не публикует порты PostgreSQL, ClickHouse или Redis. Во внешнюю сеть выходит только Caddy на портах 80 и 443.

Файл переменных окружения

Откройте /opt/langfuse/.env и замените все значения-примеры на уникальные. Адрес NEXTAUTH_URL должен в точности совпадать с публичным URL, включая https.

cd /opt/langfuse
nano .env
LANGFUSE_DOMAIN=langfuse.example.com

POSTGRES_DB=langfuse
POSTGRES_USER=langfuse
POSTGRES_PASSWORD=REPLACE_WITH_RANDOM_POSTGRES_PASSWORD

CLICKHOUSE_DB=default
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=REPLACE_WITH_RANDOM_CLICKHOUSE_PASSWORD

REDIS_PASSWORD=REPLACE_WITH_RANDOM_REDIS_PASSWORD

NEXTAUTH_URL=https://langfuse.example.com
NEXTAUTH_SECRET=REPLACE_WITH_RANDOM_BASE64_SECRET
SALT=REPLACE_WITH_RANDOM_HEX_SALT
ENCRYPTION_KEY=REPLACE_WITH_RANDOM_BASE64_KEY

DATABASE_URL=postgresql://langfuse:REPLACE_WITH_RANDOM_POSTGRES_PASSWORD@postgres:5432/langfuse
CLICKHOUSE_URL=http://clickhouse:8123
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=REPLACE_WITH_RANDOM_CLICKHOUSE_PASSWORD
REDIS_CONNECTION_STRING=redis://:REPLACE_WITH_RANDOM_REDIS_PASSWORD@redis:6379

TELEMETRY_ENABLED=false

Файл содержит пароли, поэтому не добавляйте его в Git, не пересылайте в тикетах и не вставляйте в CI-логи. Проверьте права доступа.

chmod 600 /opt/langfuse/.env
ls -l /opt/langfuse/.env

Docker Compose

Создайте файл /opt/langfuse/docker-compose.yml. Для Langfuse фиксируется тег основной ветки 3; перед плановым обновлением заменяйте его на конкретный протестированный patch-тег из официального registry. Контейнер worker обрабатывает фоновые задачи и должен работать постоянно.

cd /opt/langfuse
nano docker-compose.yml
services:
  postgres:
    image: postgres:16.6-bookworm
    restart: unless-stopped
    env_file: .env
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
      interval: 10s
      timeout: 5s
      retries: 10

  clickhouse:
    image: clickhouse/clickhouse-server:24.8
    restart: unless-stopped
    env_file: .env
    environment:
      CLICKHOUSE_DB: ${CLICKHOUSE_DB}
      CLICKHOUSE_USER: ${CLICKHOUSE_USER}
      CLICKHOUSE_PASSWORD: ${CLICKHOUSE_PASSWORD}
    volumes:
      - clickhouse_data:/var/lib/clickhouse
    ulimits:
      nofile:
        soft: 262144
        hard: 262144
    healthcheck:
      test: ["CMD-SHELL", "clickhouse-client --query 'SELECT 1'"]
      interval: 15s
      timeout: 10s
      retries: 10

  redis:
    image: redis:7.2-alpine
    restart: unless-stopped
    env_file: .env
    command: >
      redis-server --appendonly yes
      --requirepass ${REDIS_PASSWORD}
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD-SHELL", "redis-cli -a \"${REDIS_PASSWORD}\" ping | grep PONG"]
      interval: 10s
      timeout: 5s
      retries: 10

  langfuse-web:
    image: ghcr.io/langfuse/langfuse:3
    restart: unless-stopped
    env_file: .env
    depends_on:
      postgres:
        condition: service_healthy
      clickhouse:
        condition: service_healthy
      redis:
        condition: service_healthy
    environment:
      NODE_ENV: production
      NEXTAUTH_URL: ${NEXTAUTH_URL}
      NEXTAUTH_SECRET: ${NEXTAUTH_SECRET}
      SALT: ${SALT}
      ENCRYPTION_KEY: ${ENCRYPTION_KEY}
      DATABASE_URL: ${DATABASE_URL}
      CLICKHOUSE_URL: ${CLICKHOUSE_URL}
      CLICKHOUSE_USER: ${CLICKHOUSE_USER}
      CLICKHOUSE_PASSWORD: ${CLICKHOUSE_PASSWORD}
      REDIS_CONNECTION_STRING: ${REDIS_CONNECTION_STRING}
      TELEMETRY_ENABLED: ${TELEMETRY_ENABLED}
    expose:
      - "3000"

  langfuse-worker:
    image: ghcr.io/langfuse/langfuse:3
    restart: unless-stopped
    command: worker
    env_file: .env
    depends_on:
      postgres:
        condition: service_healthy
      clickhouse:
        condition: service_healthy
      redis:
        condition: service_healthy
    environment:
      NODE_ENV: production
      NEXTAUTH_SECRET: ${NEXTAUTH_SECRET}
      SALT: ${SALT}
      ENCRYPTION_KEY: ${ENCRYPTION_KEY}
      DATABASE_URL: ${DATABASE_URL}
      CLICKHOUSE_URL: ${CLICKHOUSE_URL}
      CLICKHOUSE_USER: ${CLICKHOUSE_USER}
      CLICKHOUSE_PASSWORD: ${CLICKHOUSE_PASSWORD}
      REDIS_CONNECTION_STRING: ${REDIS_CONNECTION_STRING}
      TELEMETRY_ENABLED: ${TELEMETRY_ENABLED}

  caddy:
    image: caddy:2.8-alpine
    restart: unless-stopped
    depends_on:
      - langfuse-web
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data
      - caddy_config:/config

volumes:
  postgres_data:
  clickhouse_data:
  redis_data:
  caddy_data:
  caddy_config:

У некоторых минорных выпусков Langfuse набор параметров и способ запуска worker может изменяться. Перед обновлением сверяйте раздел self-hosting официальной документации Langfuse и вывод docker compose logs langfuse-web. Не смешивайте новые образы с произвольной старой схемой переменных окружения.

Настройка Caddy и TLS

Caddy автоматически получает и продлевает TLS-сертификат Let's Encrypt. Создайте Caddyfile; почта нужна центру сертификации для уведомлений о проблемах с сертификатом.

cd /opt/langfuse
nano caddy/Caddyfile
{
    email [email protected]
}

langfuse.example.com {
    encode zstd gzip

    reverse_proxy langfuse-web:3000 {
        header_up Host {host}
        header_up X-Real-IP {remote_host}
        header_up X-Forwarded-For {remote_host}
        header_up X-Forwarded-Proto {scheme}
    }

    log {
        output stdout
        format json
    }
}

Запустите стек в фоне. Первый старт может занять несколько минут: PostgreSQL создаёт кластер, ClickHouse поднимает таблицы, а Langfuse применяет миграции.

cd /opt/langfuse
docker compose up -d
docker compose ps
docker compose logs --tail=100 langfuse-web

Проверка доступности

Проверьте контейнеры и HTTPS с самого сервера. Код ответа 200, 302 или 307 на корневом URL обычно означает, что интерфейс доступен; конкретный маршрут healthcheck зависит от версии Langfuse.

docker compose ps
curl -I http://127.0.0.1
curl -I https://langfuse.example.com
docker compose logs --tail=100 caddy

Откройте https://langfuse.example.com в браузере, создайте первого пользователя и организацию. Затем создайте проект, например production, и в его настройках сгенерируйте public key и secret key. Secret key показывается ограниченно: сохраните его в менеджере секретов приложения.

Быстрый тест из Python

На машине, где работает ваше AI-приложение, установите актуальный Python SDK Langfuse. В production передавайте ключи через переменные окружения CI/CD, Docker secrets или секрет-хранилище, а не через исходный файл.

python3 -m venv .venv
. .venv/bin/activate
pip install --upgrade langfuse openai
export LANGFUSE_PUBLIC_KEY="pk-lf-..."
export LANGFUSE_SECRET_KEY="sk-lf-..."
export LANGFUSE_BASE_URL="https://langfuse.example.com"
from langfuse import Langfuse

langfuse = Langfuse()

trace = langfuse.trace(
    name="manual-cost-test",
    user_id="demo-user",
    metadata={"environment": "test"}
)

generation = trace.generation(
    name="demo-generation",
    model="gpt-4o-mini",
    model_parameters={"temperature": 0.2},
    input=[{"role": "user", "content": "Скажи привет одним словом"}],
)

generation.end(
    output="Привет!",
    usage={"input": 12, "output": 3, "total": 15}
)

langfuse.flush()

Откройте раздел Traces в интерфейсе. Должна появиться трассировка manual-cost-test с generation и usage. Для автоматического расчёта стоимости название модели должно совпадать с моделью, настроенной в model definitions Langfuse. Если используется прокси, Azure deployment или локальная модель, создайте свою модель и укажите цену за миллион входных и выходных токенов.

Бэкапы и обслуживание

Схема: Бэкапы и обслуживание
Схема: Бэкапы и обслуживание

Снимок VPS полезен, но не заменяет независимый бэкап. Он может быть создан уже после ошибки, зависеть от одного дата-центра или не позволять быстро восстановить отдельную базу. Минимальная стратегия: ежедневный логический дамп PostgreSQL, резервная копия ClickHouse, копия .env, Caddyfile и данных объектного хранилища, если оно подключено.

Что именно нужно сохранять

Компонент Что содержит Критичность
PostgreSQL Пользователи, проекты, настройки, ключи, метаданные Критично
ClickHouse Трассы, observations, аналитические данные Критично
.env Пароли, encryption key, URL и параметры подключения Критично, хранить зашифрованно
Caddy data Сертификаты и состояние Caddy Желательно
S3/MinIO Загруженные файлы и крупные payload, если используются Зависит от конфигурации

Установка restic

Restic шифрует резервные копии на стороне сервера и умеет работать с S3-совместимым хранилищем, SFTP или отдельной машиной. Не храните единственный бэкап на том же VPS, где работает Langfuse.

sudo apt install -y restic
sudo install -d -m 700 -o deploy -g deploy /opt/langfuse/backup
nano /opt/langfuse/backup/restic.env
chmod 600 /opt/langfuse/backup/restic.env

Пример файла для S3-совместимого bucket. Подставьте свой endpoint, bucket и ключи доступа. Пароль репозитория должен быть отдельным от всех паролей Langfuse.

RESTIC_REPOSITORY=s3:https://s3.example.net/langfuse-backups
RESTIC_PASSWORD=REPLACE_WITH_LONG_UNIQUE_BACKUP_PASSWORD
AWS_ACCESS_KEY_ID=REPLACE_WITH_S3_ACCESS_KEY
AWS_SECRET_ACCESS_KEY=REPLACE_WITH_S3_SECRET_KEY

Инициализируйте пустой репозиторий один раз.

set -a
. /opt/langfuse/backup/restic.env
set +a
restic init

Скрипт ежедневного бэкапа

Скрипт создаёт дамп PostgreSQL, использует встроенный backup ClickHouse через файловую копию после краткой остановки сервиса и отправляет результат в restic. Для крупных production-баз лучше настроить ClickHouse Keeper и штатные backup destinations, но для single-node инстанса этот вариант понятен и пригоден для регулярного восстановления.

nano /opt/langfuse/scripts/backup-langfuse.sh
chmod 700 /opt/langfuse/scripts/backup-langfuse.sh
#!/usr/bin/env bash
set -euo pipefail

APP_DIR="/opt/langfuse"
BACKUP_DIR="${APP_DIR}/backup/staging"
DATE="$(date +%F-%H%M%S)"

mkdir -p "${BACKUP_DIR}"
cd "${APP_DIR}"

set -a
. "${APP_DIR}/.env"
. "${APP_DIR}/backup/restic.env"
set +a

docker compose exec -T postgres \
  pg_dump -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" \
  -Fc > "${BACKUP_DIR}/postgres-${DATE}.dump"

docker compose stop clickhouse
docker run --rm \
  -v langfuse_clickhouse_data:/source:ro \
  -v "${BACKUP_DIR}:/backup" \
  alpine:3.20 \
  sh -c "tar -czf /backup/clickhouse-${DATE}.tar.gz -C /source ."
docker compose start clickhouse

tar -czf "${BACKUP_DIR}/config-${DATE}.tar.gz" \
  "${APP_DIR}/.env" \
  "${APP_DIR}/docker-compose.yml" \
  "${APP_DIR}/caddy/Caddyfile"

restic backup "${BACKUP_DIR}"
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune

rm -f "${BACKUP_DIR}"/

Проверьте скрипт вручную до добавления cron. Если контейнер ClickHouse большой, остановка займёт время; выполняйте бэкап ночью и сообщите команде о коротком окне недоступности аналитики.

/opt/langfuse/scripts/backup-langfuse.sh
set -a && . /opt/langfuse/backup/restic.env && set +a
restic snapshots
restic check

Добавьте ежедневный запуск в 03:20 и запись журнала. Редактируйте crontab пользователя deploy.

crontab -e
20 3    /opt/langfuse/scripts/backup-langfuse.sh >> /opt/langfuse/backup/backup.log 2>&1

Обновления и контроль состояния

Для одиночного сервера обновление Langfuse — это maintenance window, а не полноценный rolling update: веб-интерфейс и ingestion могут быть кратковременно недоступны. Сначала создайте бэкап, прочитайте release notes, зафиксируйте текущие версии и только затем обновляйте образы.

cd /opt/langfuse
docker compose images
/opt/langfuse/scripts/backup-langfuse.sh
docker compose pull
docker compose up -d
docker compose logs --tail=150 langfuse-web
docker compose ps

Не запускайте без проверки команду docker system prune -a на production-сервере: она может удалить нужные образы и усложнить откат. После обновления создайте тестовую трассировку, проверьте вход в интерфейс и просмотрите ошибки контейнеров.

docker compose logs --since=15m | grep -iE "error|fatal|exception" || true
df -h
docker stats --no-stream

Troubleshooting и FAQ

Почему Caddy не получает сертификат и в логах есть ACME error?

Сначала проверьте DNS: команда dig +short A langfuse.example.com должна возвращать IP вашего сервера. Затем убедитесь, что UFW разрешает TCP-порты 80 и 443, а другой веб-сервер не занял эти порты: sudo ss -ltnp '( sport = :80 or sport = :443 )'. Если включён CDN-прокси, временно переключите запись в DNS-only. Также проверьте, что у домена нет AAAA-записи, ведущей на недоступный IPv6-сервер.

Langfuse открывается, но после входа возникает бесконечный redirect или ошибка сессии. Что делать?

Чаще всего причина — неверный NEXTAUTH_URL или изменённый NEXTAUTH_SECRET. URL обязан быть публичным адресом с https://, без лишнего пути и без localhost. Проверьте переменную командой docker compose exec langfuse-web printenv | grep NEXTAUTH, затем перезапустите контейнер. Не меняйте NEXTAUTH_SECRET без необходимости: это завершит существующие пользовательские сессии.

Почему в интерфейсе нет трассировок после отправки событий из приложения?

Проверьте три вещи: public key, secret key и LANGFUSE_BASE_URL. Ключи должны принадлежать нужному проекту, а base URL должен указывать на ваш HTTPS-домен. Затем посмотрите логи worker и web: docker compose logs --tail=100 langfuse-worker. Если приложение находится в закрытой сети, проверьте исходящий доступ к домену Langfuse. Для диагностики отправьте минимальную тестовую trace из примера выше и вызовите langfuse.flush() перед завершением процесса.

Стоимость запросов отображается как ноль или пустое значение. Почему?

Langfuse может показать usage, но не рассчитать цену, если имя модели неизвестно, токены не переданы или модель вызвана через нестандартный deployment name. Передавайте поля input, output и usage из ответа провайдера. Затем откройте настройки моделей в проекте и добавьте определение своей модели с тарифом за миллион input/output tokens. Для Azure OpenAI обычно полезно сопоставить deployment name с реальной моделью вручную.

Контейнер ClickHouse постоянно перезапускается или серверу не хватает памяти. Как исправить?

Проверьте причину через docker compose logs clickhouse и dmesg -T | grep -i oom. Сообщение OOM означает, что ядро убило процесс из-за нехватки RAM. Для устойчивой работы добавьте память до 8 GB, сократите параллельную нагрузку и убедитесь, что на диске достаточно свободного места. Временный swap допустим как аварийная мера, но он не заменяет RAM: ClickHouse на swap становится существенно медленнее.

Какой VPS-конфиг минимально подойдёт?

Для личного тестового окружения подойдёт 2 vCPU, 4 GB RAM и 60 GB SSD/NVMe, если вы не храните много событий и не запускаете несколько параллельных приложений. Для реальной команды разумный минимум — 4 vCPU, 8 GB RAM и 100 GB NVMe. Следите за docker stats, free -h и df -h в первую неделю: рост ClickHouse-data покажет фактическую потребность в диске.

Что выбрать — VPS или dedicated для этой задачи?

Для старта почти всегда достаточно VPS: он дешевле, быстрее масштабируется и позволяет быстро увеличить RAM или диск. Dedicated нужен при очень большом потоке telemetry-событий, длительном хранении, тяжёлых аналитических выборках либо требованиях к аппаратной изоляции. Хороший промежуточный этап — оставить веб-приложение на одном VPS, а PostgreSQL и ClickHouse вынести на отдельные управляемые или выделенные узлы. Это проще, чем преждевременно покупать большой сервер.

Можно ли удалить старые трассировки и уменьшить расход диска?

Да, но сначала определите retention policy: например, 30 дней для сырых production-трассировок и 90 дней для агрегированной аналитики. Удаление лучше выполнять через штатные механизмы retention и документацию текущей версии Langfuse, а не вручную удалять файлы из Docker volume. Ручное удаление каталогов ClickHouse повредит метаданные таблиц. После настройки retention контролируйте размер volumes командой docker system df -v и наличие свободного места на хосте.

Как восстановиться из резервной копии?

Разверните совместимые версии контейнеров на новом сервере, восстановите .env и Compose-конфигурацию, затем остановите сервисы. PostgreSQL-дамп формата custom восстанавливается через pg_restore внутри контейнера. Архив ClickHouse следует распаковать в пустой volume при остановленном контейнере и затем запустить ClickHouse. Перед переключением DNS обязательно проверьте вход, список проектов и несколько трассировок на временном домене или через hosts-файл.

Выводы и следующие шаги

Схема: Выводы и следующие шаги
Схема: Выводы и следующие шаги

Теперь у вас есть self-hosted Langfuse с HTTPS, изолированными внутренними базами, трассировкой LLM-вызовов и основой для расчёта стоимости токенов. Такая установка помогает находить дорогие промпты, медленные цепочки агентов и ошибки интеграций до того, как они станут проблемой для пользователей.

  1. Подключите SDK к production-приложению и начните с трассировки одного критичного пользовательского сценария.
  2. Настройте модели и цены, затем создайте регулярный отчёт по стоимости на пользователя, проект или endpoint.
  3. При росте нагрузки вынесите ClickHouse и PostgreSQL на отдельные узлы, добавьте мониторинг диска, памяти и успешности бэкапов.

Был ли этот гайд полезен?

Ваш отзыв помогает нам улучшать гайды.

Поделиться записью:

Отправьте гайд тому, кому он может пригодиться.

Telegram VKVK WhatsApp Facebook LinkedIn XX

langfuse self-hosted: трассировка и стоимость llm-запросов
support_agent
Valebyte Support
Usually replies within minutes
Hi there!
Send us a message and we'll reply as soon as possible.