Self-Hosting Formbricks with Docker Compose

Why Self-Host Your Forms?

Google Forms sends your respondent data to Google. Typeform charges $29+/month for basic logic branching. Formbricks gives you both — a polished form builder with conditional logic, analytics, and multi-language support — entirely on your own infrastructure.

Formbricks is an open-source experience management platform. It handles surveys, product feedback forms, website popups, and in-app micro-surveys. The form builder is drag-and-drop with question types, logic jumps, and response piping. Results come with built-in analytics — no external tools needed.

Prerequisites

  • A Linux server (Ubuntu 22.04+ recommended)
  • Docker and Docker Compose installed (guide)
  • 2 GB RAM minimum
  • 15 GB free disk space
  • A domain name (required for production)
  • SMTP access for email notifications (optional but recommended)
ResourceMinimumRecommended
RAM2 GB (total stack)4 GB
CPU1 core2 cores
Disk15 GB30 GB

Formbricks runs on Next.js with PostgreSQL (pgvector) and Redis. The stack is heavier than a static form tool but lighter than most survey platforms.

Docker Compose Configuration

Create a docker-compose.yml:

services:
  formbricks:
    image: ghcr.io/formbricks/formbricks:v4.7.5
    container_name: formbricks
    depends_on:
      formbricks-db:
        condition: service_healthy
      formbricks-redis:
        condition: service_started
    environment:
      - WEBAPP_URL=${WEBAPP_URL}
      - NEXTAUTH_URL=${WEBAPP_URL}
      - DATABASE_URL=postgres://formbricks:${DB_PASSWORD}@formbricks-db:5432/formbricks
      - NEXTAUTH_SECRET=${NEXTAUTH_SECRET}
      - ENCRYPTION_KEY=${ENCRYPTION_KEY}
      - CRON_SECRET=${CRON_SECRET}

      # Email (optional but needed for invitations and password resets)
      - MAIL_FROM=${MAIL_FROM:[email protected]}
      - SMTP_HOST=${SMTP_HOST:-}
      - SMTP_PORT=${SMTP_PORT:-587}
      - SMTP_USER=${SMTP_USER:-}
      - SMTP_PASSWORD=${SMTP_PASSWORD:-}
      - SMTP_SECURE_ENABLED=${SMTP_SECURE:-1}
    ports:
      - "3000:3000"
    restart: unless-stopped

  formbricks-db:
    image: pgvector/pgvector:pg17
    container_name: formbricks-db
    environment:
      - POSTGRES_DB=formbricks
      - POSTGRES_USER=formbricks
      - POSTGRES_PASSWORD=${DB_PASSWORD}
    volumes:
      - formbricks_db:/var/lib/postgresql/data
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U formbricks"]
      interval: 10s
      timeout: 5s
      retries: 5

  formbricks-redis:
    image: valkey/valkey:8-alpine
    container_name: formbricks-redis
    volumes:
      - formbricks_redis:/data
    restart: unless-stopped

volumes:
  formbricks_db:
  formbricks_redis:

Create a .env file:

# Your public URL — MUST match exactly (no trailing slash)
WEBAPP_URL=https://forms.example.com

# Database password — change this
DB_PASSWORD=change_me_strong_password

# Generate all three secrets:
# openssl rand -hex 32
NEXTAUTH_SECRET=generate_me
ENCRYPTION_KEY=generate_me
CRON_SECRET=generate_me

# Email (optional — needed for invitations)
MAIL_FROM=[email protected]
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=apikey
SMTP_PASSWORD=your_smtp_password
SMTP_SECURE=1

Generate the secrets:

for var in NEXTAUTH_SECRET ENCRYPTION_KEY CRON_SECRET; do
  echo "${var}=$(openssl rand -hex 32)" >> .env
done

Start the stack:

docker compose up -d

Initial Setup

  1. Open https://forms.example.com in your browser
  2. Create your account — the first user becomes the organization admin
  3. Complete the onboarding: organization name, role, and use case
  4. You’re dropped into the dashboard — click Create Survey to build your first form

Question Types Available

TypeDescription
Single SelectRadio buttons / dropdown
Multi SelectCheckboxes
Open TextShort or long text input
RatingStar rating or emoji scale
NPSNet Promoter Score (0-10)
CTACall-to-action button
ConsentGDPR/privacy consent checkbox
DateDate picker
File UploadDrag-and-drop file attachment
AddressStructured address fields
MatrixGrid/table questions
Picture SelectionImage-based choices

All question types support conditional logic — show or hide questions based on previous answers.

Distribution Methods

Formbricks supports multiple ways to reach respondents:

MethodHow It WorksBest For
Link surveysShareable URL, standalone form pageExternal surveys, feedback collection
Website surveysJavaScript widget, in-page popupOn-site feedback, exit intent
App surveysSDK integration (React, Next.js, Vue)In-app product feedback

Link surveys work out of the box. Website and app surveys require embedding the Formbricks SDK in your frontend code.

Configuration

Custom Branding

Under Organization Settings → Branding, customize:

  • Logo and favicon
  • Primary color
  • Background color
  • Survey URL slug (e.g., forms.example.com/s/your-brand)

Webhooks

Forward survey responses to external services. Under Integrations → Webhooks:

https://n8n.example.com/webhook/formbricks-response

Pair with n8n or Activepieces for automated workflows — send responses to Slack, create tickets, update spreadsheets.

Response Notifications

Configure email notifications per survey — get notified on every response or on a daily/weekly digest. Requires SMTP configuration.

Reverse Proxy

Formbricks runs on port 3000. For production, put it behind an SSL-terminating reverse proxy.

Caddy:

forms.example.com {
    reverse_proxy formbricks:3000
}

Critical: WEBAPP_URL and NEXTAUTH_URL must both match your public URL exactly (including https://). Mismatches cause silent authentication failures.

See Reverse Proxy Setup for Nginx and Traefik configs.

Backup

PostgreSQL holds all survey definitions and responses:

docker exec formbricks-db pg_dump -U formbricks formbricks > formbricks-backup.sql

Redis data is cache — not critical to back up. See Backup Strategy for scheduling.

Troubleshooting

Login page loads but authentication fails silently

Symptom: Clicking login does nothing, or you get redirected back to the login page.

Fix: WEBAPP_URL and NEXTAUTH_URL must be identical and must match the URL you’re accessing in the browser. If you access https://forms.example.com but set http://forms.example.com (no s), auth will fail. Check both variables.

”Cannot connect to database” on startup

Symptom: Formbricks container restarts repeatedly with database connection errors.

Fix: PostgreSQL must be healthy before Formbricks starts. The health check in the compose file handles this, but if you see issues:

docker logs formbricks-db

Check that the password in DATABASE_URL matches POSTGRES_PASSWORD.

Invitation emails not sending

Symptom: Team members don’t receive invitation emails.

Fix: SMTP must be configured. Without it, Formbricks can’t send any emails. Test your SMTP settings:

docker exec formbricks env | grep SMTP

Verify the host, port, and credentials are correct. Many SMTP providers require an app password, not your login password.

Surveys load slowly

Symptom: Survey pages take 5+ seconds to load for respondents.

Fix: Ensure Redis is running and connected. Without Redis, Formbricks falls back to slow database queries for caching. Check Redis connectivity:

docker exec formbricks-redis valkey-cli ping

Should return PONG.

Formbricks vs Google Forms

FeatureFormbricksGoogle Forms
Conditional logicYes (complex branching)Basic (go to section)
Custom brandingFull controlGoogle branding
Response analyticsBuilt-in dashboardsBasic charts
Data ownershipYour serverGoogle’s servers
Website popupsYes (JS widget)No
In-app surveysYes (SDK)No
WebhooksYesNo
PriceFree (self-hosted)Free (Google-hosted)
File uploadsYesYes
NPS surveysYesNo (manual)
API accessFull REST APIGoogle Sheets API

Verdict

Formbricks is the most capable self-hosted form builder available. It goes beyond basic form creation — the website widget, in-app SDK, and conditional logic make it a real alternative to Typeform and even product feedback tools like Hotjar. The analytics dashboards mean you don’t need to export to a spreadsheet to understand your data.

Use Formbricks if: You need forms with logic branching, in-app surveys, or website popups. Particularly strong for product teams collecting user feedback.

Look elsewhere if: You just need a simple poll or voting tool — Rallly (scheduling polls) or LimeSurvey (academic surveys) are simpler. If you need a feature-request board, see Fider.

Comments