MAATRIX / Блог / Formbricks в Docker Compose: готовый файл

Formbricks в Docker Compose: готовый файл

MAATRIX

Typeform красивый, но для российского пользователя это лотерея: то карта не проходит, то лимит бесплатного тарифа режет опрос на середине сбора ответов, то данные респондентов лежат непонятно где. Formbricks закрывает все три проблемы разом — это open-source платформа опросов с полноценной логикой ветвления, которую вы разворачиваете на своём сервере и полностью контролируете. Ниже — рабочий docker-compose.yml для теста и отдельная конфигурация для продакшена с вынесенной базой, HTTPS и почтой.

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

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

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

Что такое Formbricks и зачем он вместо Typeform

Formbricks — это не просто конструктор форм, а платформа experience management: опросы со ссылкой (link surveys) для рассылок и лендингов, встраиваемые виджеты для in-app опросов внутри вашего продукта, и общая база ответов с сегментацией по пользователям. Из коробки есть:

  • Логика ветвления — переход к следующему вопросу зависит от ответа на предыдущий, можно строить многоступенчатые сценарии (NPS → уточняющий вопрос только у недовольных → открытый комментарий).
  • Разные типы вопросов — рейтинг, NPS, множественный выбор, matrix, загрузка файла, дата, ranking.
  • Триггеры и таргетинг для встраиваемых опросов — показ по действию пользователя, по URL, по проценту аудитории.
  • Вебхуки и интеграции — отправка ответов наружу без ручного экспорта, что удобно тянуть в n8n для дальнейшей автоматизации — например, класть новые ответы в CRM или пересылать негативный NPS в Telegram.
  • Собственный домен и брендинг без пометок «сделано на Typeform» внизу формы.

Важный нюанс: Formbricks распространяется как community edition с собственной лицензией, а не чистым MIT — self-hosted использование она разрешает свободно, но перед перепродажей SaaS на её основе третьим лицам стоит прочитать актуальные условия в репозитории проекта.

Минус тот же, что у любого self-hosted инструмента: обновления, бэкапы и мониторинг — теперь ваша забота. Docker Compose снимает основную часть боли с установкой, дальше в статье закрываем HTTPS и бэкапы.

Что нужно перед установкой

Для комфортного старта достаточно:

  • VPS с 2 vCPU и 4 ГБ RAM — ориентир для одного проекта и умеренного трафика; под десятки одновременных виджетов на высоконагруженном сайте закладывайте больше и следите за CPU базы.
  • Docker и Docker Compose plugin — на Ubuntu 24.04 это команда apt install docker-compose-plugin после подключения официального репозитория Docker.
  • Домен, А-запись которого указывает на IP сервера — Formbricks строит ссылки на опросы и письма-приглашения от публичного URL, без него ссылки будут битыми.
  • Открытые наружу порты 80/443 для выпуска сертификата, если HTTPS терминируете прямо на сервере.
  • SMTP-доступ — без него не заработают приглашения в команду и email-триггеры опросов.

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

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

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

Docker Compose: минимальный запуск для теста

Для локального теста или внутреннего пилота хватает связки из самого приложения и PostgreSQL в соседнем контейнере — без Redis и без внешнего reverse proxy, HTTPS в этом варианте пробрасываем позже.

version: "3.8"

services:
  postgres:
    image: postgres:16-alpine
    container_name: formbricks_db
    restart: unless-stopped
    environment:
      POSTGRES_DB: formbricks
      POSTGRES_USER: formbricks
      POSTGRES_PASSWORD: "замените-на-случайный-пароль"
    volumes:
      - formbricks_db:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U formbricks"]
      interval: 10s
      timeout: 5s
      retries: 5

  formbricks:
    image: formbricks/formbricks:latest
    container_name: formbricks
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
    environment:
      DATABASE_URL: "postgresql://formbricks:замените-на-случайный-пароль@postgres:5432/formbricks?schema=public"
      NEXTAUTH_URL: "https://forms.example.com"
      WEBAPP_URL: "https://forms.example.com"
      NEXTAUTH_SECRET: "замените-командой-ниже"
      ENCRYPTION_KEY: "замените-командой-ниже"
      CRON_SECRET: "замените-командой-ниже"
    ports:
      - "127.0.0.1:3000:3000"
    volumes:
      - formbricks_uploads:/home/nextjs/apps/web/uploads

volumes:
  formbricks_db:
  formbricks_uploads:

Тег образа стоит зафиксировать конкретной версией, а не latest — проверьте актуальный тег на Docker Hub перед запуском, чтобы автоматический docker compose pull не подтянул минорную версию с ломающими изменениями в схеме базы посреди рабочего дня.

Поднимаем и смотрим логи первого старта, миграции базы применяются автоматически при первом запуске контейнера:

mkdir -p ~/formbricks && cd ~/formbricks
# вставляем docker-compose.yml из примера выше
docker compose up -d
docker compose logs -f formbricks

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

ПеременнаяЗа что отвечаетЧто будет при слабом значении
NEXTAUTH_SECRETподписывает сессии авторизациипри компрометации значения можно подделать сессионный токен и войти под чужим аккаунтом
ENCRYPTION_KEYшифрует чувствительные поля в базе (например, API-ключи интеграций)при потере или смене ключа расшифровать старые данные уже не получится — храните значение так же бережно, как пароль от базы
CRON_SECRETзащищает служебный endpoint периодических задач от постороннего вызовабез надёжного значения посторонний может дёргать внутренние cron-задачи приложения напрямую

Генерируются одной командой каждая:

openssl rand -hex 32

Вынесите все три значения вместе с паролем от Postgres в отдельный .env рядом с docker-compose.yml — это упрощает ротацию и не даёт случайно закоммитить секреты в git, если конфиг хранится в репозитории:

POSTGRES_PASSWORD=...
NEXTAUTH_SECRET=...
ENCRYPTION_KEY=...
CRON_SECRET=...

и подставьте ${POSTGRES_PASSWORD} и остальные переменные в docker-compose.yml вместо значений в открытом виде.

Продакшен-конфигурация: почта, Redis и загрузка файлов

Как только Formbricks становится рабочим инструментом с реальными опросами и приглашённой командой, добавьте SMTP для писем и Redis — он снижает нагрузку на Postgres на часто запрашиваемых данных (настройки опросов, рейт-лимиты API) при заметном трафике.

  redis:
    image: redis:7-alpine
    container_name: formbricks_redis
    restart: unless-stopped
    command: redis-server --appendonly yes
    volumes:
      - formbricks_redis:/data

  formbricks:
    image: formbricks/formbricks:latest
    restart: unless-stopped
    depends_on:
      - postgres
      - redis
    environment:
      DATABASE_URL: "postgresql://formbricks:${POSTGRES_PASSWORD}@postgres:5432/formbricks?schema=public"
      REDIS_URL: "redis://redis:6379"
      NEXTAUTH_URL: "https://forms.example.com"
      WEBAPP_URL: "https://forms.example.com"
      NEXTAUTH_SECRET: "${NEXTAUTH_SECRET}"
      ENCRYPTION_KEY: "${ENCRYPTION_KEY}"
      CRON_SECRET: "${CRON_SECRET}"
      SMTP_HOST: "smtp.example.com"
      SMTP_PORT: "587"
      SMTP_USER: "forms@example.com"
      SMTP_PASSWORD: "${SMTP_PASSWORD}"
      SMTP_SECURE_ENABLED: "1"
      MAIL_FROM: "forms@example.com"
    ports:
      - "127.0.0.1:3000:3000"
    volumes:
      - formbricks_uploads:/home/nextjs/apps/web/uploads

Не забудьте добавить formbricks_redis: в блок volumes: внизу файла. Загрузка файлов (например, ответ на вопрос с прикреплением скриншота) по умолчанию идёт на локальный volume — для одного сервера этого достаточно, но если хотите вынести файлы в S3-совместимое хранилище и упростить бэкапы, конкретные названия переменных S3-интеграции для вашей версии сверьте с актуальной документацией проекта — они периодически меняются между релизами.

HTTPS и reverse proxy

Formbricks сам по себе слушает только plain HTTP на 3000 порту — сертификат и терминацию TLS берёт на себя внешний reverse proxy. Если на сервере уже настроен Traefik как reverse proxy для Docker, достаточно добавить лейблы к сервису formbricks вместо проброса порта наружу:

  formbricks:
    # ...остальные настройки как выше
    ports: []
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.formbricks.rule=Host(`forms.example.com`)"
      - "traefik.http.routers.formbricks.entrypoints=websecure"
      - "traefik.http.routers.formbricks.tls.certresolver=letsencrypt"
      - "traefik.http.services.formbricks.loadbalancer.server.port=3000"
    networks:
      - traefik-public

networks:
  traefik-public:
    external: true

Если Traefik ещё не установлен, разверните его тем же способом, что и Formbricks — отдельным compose-файлом с сетью traefik-public, к которой затем подключаются остальные сервисы. Такая схема удобнее, если на одном сервере вы уже держите несколько self-hosted сервисов — не нужно выделять под каждый отдельный IP или пару портов 80/443.

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

После старта контейнеров откройте https://forms.example.com — первая зарегистрированная учётка становится администратором организации, дальнейших пользователей приглашаете по почте через настроенный SMTP.

Логика ветвления настраивается прямо в конструкторе опроса: у каждого вопроса есть блок «Logic», где вы задаёте условие («если ответ равен / содержит / больше значения X») и целевой следующий вопрос вместо стандартного «следующий по порядку». Типичный сценарий: вопрос-шлюз с оценкой NPS от 0 до 10, дальше при оценке ≤ 6 — переход к открытому вопросу «что можно улучшить», при оценке ≥ 9 — к вопросу «оставите отзыв публично?», а остальным сразу экран благодарности без лишних вопросов.

Так опрос не растягивается для тех, чей ответ и так понятен, а уточнения получают только нужные сегменты. Ответы доступны в разделе Responses с фильтрами и экспортом в CSV, а через вебхуки их можно забирать в реальном времени во внешние системы.

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

Бэкапить нужно базу данных и, если не вынесли в S3, локальный volume с загруженными файлами.

Дамп PostgreSQL из контейнера:

docker compose exec postgres pg_dump -U formbricks formbricks | gzip > formbricks_$(date +%F).sql.gz

Восстановление на чистую базу:

gunzip -c formbricks_2026-08-20.sql.gz | docker compose exec -T postgres psql -U formbricks formbricks

Для регулярных автоматических снапшотов без ручных cron-скриптов удобно поднять рядом BorgBackup в отдельном контейнере — дедупликация и шифрование заметно экономят место при ежедневных бэкапах базы и volume с файлами.

Обновление — меняем тег образа и пересоздаём контейнер приложения:

docker compose pull formbricks
docker compose up -d formbricks
docker compose logs -f formbricks

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

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

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

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

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

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

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

Чем Formbricks отличается от связки Baserow с формами?

Baserow — это табличная база данных, формы там лишь одна из функций, а Formbricks заточен именно под опросы: ветвление логики, in-app виджеты, таргетинг по сегментам. Нужна реляционная база — берите Baserow, нужны продуктовые опросы и NPS — Formbricks.

Можно ли встроить опрос прямо в свой сайт, а не только слать ссылку?

Да, есть JS-виджет для встраивания с показом по триггерам (действие пользователя, прокрутка, задержка на странице) и SDK для мобильных приложений — детали смотрите в разделе документации про in-app surveys.

Что если я не настрою SMTP сразу?

Formbricks запустится и опросы через ссылку будут работать, но пригласить коллег по почте или получить уведомление о новом ответе не получится, пока не пропишете SMTP-переменные и не перезапустите контейнер.

Нужен ли Redis для небольшого проекта?

Нет, для одного проекта и умеренного трафика Formbricks работает и без него — Redis в первую очередь снимает нагрузку на Postgres при большом количестве запросов к виджетам, добавляйте его по мере роста, а не заранее.

Как перенести Formbricks с одного сервера на другой?

Снимите дамп Postgres и заберите volume с загрузками (или экспортируйте бакет S3, если файлы там), поднимите такой же docker-compose.yml на новом сервере с теми же секретами NEXTAUTH_SECRET и ENCRYPTION_KEY — без совпадения ключа шифрования часть зашифрованных в базе данных (например, сохранённые API-ключи интеграций) не расшифруется.

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

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

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