Skip to main content

Self-Host Budibase: Open Source Retool Alternative 2026

·OSSAlt Team
budibaseinternal-toolsself-hostingdockerlow-code

How to Self-Host Budibase: The Open Source Retool Alternative in 2026

TL;DR

Retool charges $10–$50/user/month for internal tools. Budibase is the open source alternative — a low-code platform for building data-backed apps, CRUD interfaces, and internal dashboards, self-hosted for the price of a VPS. It connects to PostgreSQL, MySQL, MongoDB, REST APIs, Airtable, S3, and more. Unlike Retool which runs in Retool's cloud by default, Budibase can run entirely on your infrastructure — your data never leaves your servers. The self-hosted community edition is free; the Business tier ($125/month for 25 users) adds advanced RBAC and SSO.

Key Takeaways

  • Open source Retool alternative: drag-and-drop UI builder for internal tools, connected to your databases
  • Self-hostable: Docker Compose or Kubernetes, data stays on your infra
  • Data sources: PostgreSQL, MySQL, MSSQL, MongoDB, CouchDB, Oracle, Elasticsearch, Redis, S3, REST APIs, GraphQL, Google Sheets
  • Automation: built-in workflow engine (cron, webhooks, database triggers)
  • RBAC: role-based access control — not just read/write but per-table, per-row policies
  • GitHub stars: 22,000+ (one of the most-starred internal tools projects)
  • License: GPL v3 (community) / commercial (premium features)

Why Budibase Over AppSmith or ToolJet?

FeatureBudibaseAppSmithToolJet
Built-in DBCouchDB-based BudiBase DBPostgreSQL
Automation/Workflows✅ built-inLimited
Public apps
Self-host difficultyEasyEasyEasy
UI Components~50~45~45
Best forFull-stack internal appsData-heavy dashboardsAutomation-heavy tools

Budibase's differentiator is its built-in database (BudiBase DB, backed by CouchDB) — you can build full CRUD apps without connecting an external database. Combined with its automation engine, it's the most "complete" self-hosted option for building internal tools from scratch.


Self-Hosting with Docker Compose

Prerequisites

  • Docker and Docker Compose
  • 2GB RAM minimum (4GB recommended)
  • Domain with DNS pointing to your server (for production)

docker-compose.yml

version: "3"

services:
  minio-service:
    container_name: budi-minio
    image: minio/minio
    volumes:
      - minio_data:/data
    environment:
      MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY}
      MINIO_SECRET_KEY: ${MINIO_SECRET_KEY}
    command: server /data --console-address ":9001"
    restart: unless-stopped

  couch-init:
    container_name: budibase-couchdb-init
    image: ibmcom/couchdb3
    environment:
      COUCHDB_USER: ${COUCHDB_USER}
      COUCHDB_PASSWORD: ${COUCHDB_PASSWORD}
    command: curl -X PUT http://${COUCHDB_USER}:${COUCHDB_PASSWORD}@couchdb-service:5984/_users
    depends_on:
      - couchdb-service

  couchdb-service:
    container_name: budibase-couchdb
    image: budibase/couchdb
    environment:
      COUCHDB_USER: ${COUCHDB_USER}
      COUCHDB_PASSWORD: ${COUCHDB_PASSWORD}
    volumes:
      - couchdb_data:/opt/couchdb/data
    restart: unless-stopped

  redis-service:
    container_name: budibase-redis
    image: redis
    command: redis-server --requirepass ${REDIS_PASSWORD}
    volumes:
      - redis_data:/data
    restart: unless-stopped

  app-service:
    container_name: budibase-app
    image: budibase/apps:latest
    environment:
      SELF_HOSTED: 1
      COUCH_DB_URL: http://${COUCHDB_USER}:${COUCHDB_PASSWORD}@couchdb-service:5984
      REDIS_URL: redis-service:6379
      REDIS_PASSWORD: ${REDIS_PASSWORD}
      MINIO_URL: http://minio-service:9000
      MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY}
      MINIO_SECRET_KEY: ${MINIO_SECRET_KEY}
      JWT_SECRET: ${JWT_SECRET}
      APP_PORT: 4002
      WORKER_URL: http://worker-service:4003
      BUDIBASE_ENVIRONMENT: PRODUCTION
    depends_on:
      - couchdb-service
      - redis-service
      - minio-service
    restart: unless-stopped

  worker-service:
    container_name: budibase-worker
    image: budibase/worker:latest
    environment:
      SELF_HOSTED: 1
      PORT: 4003
      REDIS_URL: redis-service:6379
      REDIS_PASSWORD: ${REDIS_PASSWORD}
      JWT_SECRET: ${JWT_SECRET}
      COUCH_DB_URL: http://${COUCHDB_USER}:${COUCHDB_PASSWORD}@couchdb-service:5984
      MINIO_URL: http://minio-service:9000
      MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY}
      MINIO_SECRET_KEY: ${MINIO_SECRET_KEY}
    depends_on:
      - redis-service
      - minio-service
    restart: unless-stopped

  proxy-service:
    container_name: budibase-nginx
    image: budibase/proxy:latest
    environment:
      PROXY_RATE_LIMIT_WEBHOOKS_PER_SECOND: 10
      PROXY_RATE_LIMIT_API_PER_SECOND: 20
    depends_on:
      - app-service
      - worker-service
      - minio-service
    ports:
      - "80:10000"
    restart: unless-stopped

volumes:
  couchdb_data:
  minio_data:
  redis_data:

.env file

# .env — copy and customize
COUCHDB_USER=admin
COUCHDB_PASSWORD=change-this-strong-password
REDIS_PASSWORD=change-this-redis-password
MINIO_ACCESS_KEY=change-this-minio-access
MINIO_SECRET_KEY=change-this-minio-secret
JWT_SECRET=change-this-jwt-secret-32-chars-min

Generate secrets:

openssl rand -hex 32  # Run 3x for each secret

Start and Configure

git clone https://github.com/Budibase/budibase.git
cd budibase/hosting
cp .env.example .env
# Edit .env with your secrets
docker compose up -d

# Check status
docker compose ps
# Access at http://localhost:80

On first launch, Budibase walks you through creating your admin account.


Connecting Data Sources

PostgreSQL Connection

1. Open your Budibase app
2. Click "Data" tab
3. "Add Source" → PostgreSQL
4. Fill in:
   - Host: your-postgres-host.internal
   - Port: 5432
   - Database: mydb
   - User: app_readonly  (use a read-only user for safety)
   - Password: ***
5. Click "Fetch Tables" — Budibase lists all tables
6. Click each table you want to use → "Fetch"

Budibase auto-generates a CRUD interface for each table. You can immediately build a data grid that reads, filters, sorts, creates, and deletes rows without writing any code.

REST API Connection

1. "Add Source" → REST API
2. Base URL: https://api.yourservice.com/v1
3. Headers:
   - Authorization: Bearer {{API_KEY}}
   (use Budibase's binding syntax {{}} to reference env variables)
4. Create queries:
   - GET /users → List users
   - POST /users → Create user
   - GET /users/{{userId}} → Get user by ID

Building Your First App: An Admin Dashboard

Step 1: Set Up the Data

Connect your PostgreSQL users table. Budibase fetches the schema and creates default CRUD queries.

Step 2: Create Screens

New Screen → Table → Select "users" table

Budibase generates a full data grid with pagination, sorting, filtering, create/edit/delete forms. Customize the columns shown, add conditional formatting (red for status = 'suspended'), and add action buttons.

Step 3: Add Custom Automation

Create an automation that fires when a new user signs up:

Automation → Create
Trigger: Database row created (users table, condition: created_at > NOW() - INTERVAL 1 MINUTE)
Step 1: Send email (built-in SMTP)
  To: admin@yourcompany.com
  Subject: New user signed up
  Body: {{trigger.row.email}} just registered
Step 2: Slack webhook
  URL: {{env.SLACK_WEBHOOK_URL}}
  Body: { "text": "New signup: {{trigger.row.email}}" }

Role-Based Access Control

Budibase has four built-in roles, customizable per-app:

RoleDefault Permissions
AdminFull access
Power UserCreate, edit, delete data
Basic UserRead + limited write
PublicUnauthenticated access

Configure per-screen:

Screen Settings → Access → Set minimum role to "Power User"

For row-level security:

Data Source → users table → Row Access
Filter: id = {{ currentUser.id }}
# Users can only see their own rows

Custom Components and Plugins

Budibase supports custom components built in Svelte — for use cases the built-in component library doesn't cover:

# Initialize a new plugin
npx @budibase/cli@latest component init my-chart-component
cd my-chart-component
npm install
npm run build

# Upload to your Budibase instance
npx @budibase/cli@latest upload plugin
# → Enter your Budibase URL and API key
# Component appears in the UI builder immediately

The plugin system also supports data source plugins for connecting to custom APIs or databases not in Budibase's built-in list.


Automation: Scheduled Tasks and Webhooks

Budibase's automation engine replaces simple Zapier/n8n workflows for internal use cases:

Daily Report Email

Automation → Create
Name: Daily Active Users Report
Trigger: Schedule → Daily at 8:00 AM

Step 1: Query data
  Data source: PostgreSQL
  Query: SELECT COUNT(*) as daily_users FROM users
         WHERE last_seen >= NOW() - INTERVAL 24 HOURS

Step 2: Send email
  Provider: SMTP (configure in settings)
  To: team@company.com
  Subject: Daily Active Users — {{steps.1.rows[0].daily_users}} users yesterday
  Body: |
    Hi team,

    Yesterday's active user count: {{steps.1.rows[0].daily_users}}

    View the full dashboard: https://budibase.company.com/app/dashboard

Step 3: Post to Slack
  Webhook URL: {{env.SLACK_WEBHOOK}}
  Body: { "text": "📊 {{steps.1.rows[0].daily_users}} active users yesterday" }

Webhook Trigger (External Events)

Automation → Create
Trigger: Webhook
  → Copy the webhook URL: https://budibase.company.com/api/v1/automations/xxx/trigger

Step 1: Update database
  Data source: PostgreSQL
  Query: UPDATE orders SET status = '{{trigger.body.status}}'
         WHERE id = '{{trigger.body.orderId}}'

Step 2: Send notification
  ...

Use the webhook URL in your payment processor, Stripe, or any external service to trigger Budibase automations on events.


Environment Variables and Secrets

Budibase has a built-in environment variable system for managing secrets across automations and queries:

Settings → Environment Variables
→ Add: STRIPE_API_KEY = sk_live_xxxx
→ Add: SLACK_WEBHOOK = https://hooks.slack.com/...
→ Add: INTERNAL_API_URL = https://api.company.internal

Reference them in queries and automations with {{env.STRIPE_API_KEY}}. Variables are encrypted at rest and never exposed to the frontend — they're server-side only.


Multi-App and Team Management

Budibase supports multiple apps per instance — organize by team or use case:

  • Customer Support app: connected to your helpdesk database
  • Finance app: connected to accounting PostgreSQL, restricted to finance team
  • DevOps app: connected to Kubernetes API, restricted to engineers
  • HR app: connected to HR system, restricted by department

Each app has independent RBAC, its own data sources, and separate publish/edit permissions. The admin panel shows all apps with their last modified date and access stats.


Scaling Budibase

The default Docker Compose setup is single-node. For higher availability:

# Scale app and worker services
docker compose up -d --scale app-service=3 --scale worker-service=2

For true HA, Budibase's enterprise documentation covers Kubernetes deployment with multiple replicas, shared CouchDB cluster, and Redis Sentinel. Most self-hosters don't need this — a single node handles hundreds of internal users comfortably.

Resource requirements by usage:

  • 1-25 users: 2 vCPU, 4GB RAM ($12/month on Hetzner)
  • 25-100 users: 4 vCPU, 8GB RAM ($25/month on Hetzner)
  • 100+ users: Consider the cloud offering or HA setup

Production Hardening

TLS with Certbot

# Install certbot on the host
certbot certonly --standalone -d budibase.yourdomain.com

# Update nginx config in budibase/hosting/proxy/nginx.conf
# Or put a Caddy/Traefik proxy in front

Regular Backups

#!/bin/bash
# backup-budibase.sh
DATE=$(date +%Y%m%d_%H%M)

# CouchDB backup (all databases)
docker exec budibase-couchdb \
  curl -X GET "http://admin:password@localhost:5984/_all_dbs" | \
  jq -r '.[]' | while read db; do
    curl -X GET "http://admin:password@localhost:5984/$db/_all_docs?include_docs=true" \
      > /backups/budibase/couch_${db}_${DATE}.json
  done

# MinIO backup (file attachments)
docker run --rm \
  -v /backups/budibase/minio:/backup \
  minio/mc mirror myminio/budibase /backup

echo "Budibase backup complete"

Upgrading Budibase

cd budibase/hosting
docker compose pull         # Pull latest images
docker compose up -d        # Restart with new images
docker compose logs -f      # Watch for migration logs

Budibase runs database migrations automatically on startup. Major version upgrades may require following the migration guide in the changelog.


Cost Comparison: Retool vs Budibase Self-Hosted

PlanRetoolBudibase Self-Hosted
5 users$250/month~$10/month (VPS)
25 users$1,250/month~$20/month (VPS)
50 users$2,500/month~$30/month (VPS)
SSO/SAML+$500/monthBusiness tier ($125/mo)
Audit logsEnterpriseBusiness tier
Data locationRetool's cloudYour server

For a 10-person startup, switching from Retool to self-hosted Budibase saves roughly $1,000-$2,500/month — meaningful for early-stage teams. The trade-off is operational overhead: you're responsible for updates, backups, and uptime.


Methodology

  • GitHub data from github.com/Budibase/budibase, March 2026
  • Pricing data from budibase.com/pricing, March 2026
  • Setup guide based on Budibase official documentation (docs.budibase.com)
  • Version: Budibase 3.x (check GitHub releases for current version)

Find more open source Retool alternatives on OSSAlt — self-hosting guides, community ratings, and feature comparisons.

Related: How to Migrate from Retool to Appsmith 2026 · Best Open Source Alternatives to Retool 2026 · Best Open Source Developer Tools in 2026

Comments