Skip to main content

Self-Hosting Installation

This guide covers deploying Better Hub on your own infrastructure using Docker.

Prerequisites

  • Node.js 22+
  • pnpm 10+
  • Docker and Docker Compose
  • A GitHub OAuth App (create one here)

Quick Start with Docker

1

Clone the repository

git clone https://github.com/better-auth/better-hub.git
cd better-hub
2

Start infrastructure services

Launch PostgreSQL and Redis with Docker Compose:
docker compose up -d
This starts:
  • PostgreSQL on localhost:54320
  • Redis (internal)
  • Redis REST proxy on localhost:8079
3

Configure environment variables

Copy the example environment file and fill in required values:
cp apps/web/.env.example apps/web/.env
See Configuration below for required values.
4

Install dependencies

pnpm install
5

Run database migrations

cd apps/web && npx prisma migrate dev && cd ../..
6

Start the development server

pnpm dev
Better Hub will be available at http://localhost:3000.

Configuration

Required Environment Variables

Edit apps/web/.env with these required values:

Authentication

Create a GitHub OAuth App at github.com/settings/developers:
GITHUB_CLIENT_ID=your_github_oauth_app_client_id
GITHUB_CLIENT_SECRET=your_github_oauth_app_client_secret
When creating your OAuth App, set the Homepage URL to http://localhost:3000 and the Authorization callback URL to http://localhost:3000/api/auth/callback/github.
Generate a random 32-character secret for session encryption:
# Generate with openssl
openssl rand -hex 16
Then add to .env:
BETTER_AUTH_SECRET=your_generated_32_char_string
BETTER_AUTH_URL=http://localhost:3000
NEXT_PUBLIC_APP_URL=http://localhost:3000

Database

For the Docker Compose setup:
DATABASE_URL=postgresql://postgres:postgres@localhost:54320/better_hub
The default password is postgres. To change it, set POSTGRES_PASSWORD before running docker compose up.

Redis

For the Docker Compose setup with REST proxy:
UPSTASH_REDIS_REST_URL=http://localhost:8079
UPSTASH_REDIS_REST_TOKEN=local_token
The default token is local_token. For production, set SRH_TOKEN to a secure value before running docker compose up.

AI Configuration

Ghost AI requires API keys for AI providers.

Required for Ghost

# OpenRouter powers Ghost assistant
OPEN_ROUTER_API_KEY=your_open_router_api_key

# Anthropic for specific AI tasks
ANTHROPIC_API_KEY=your_anthropic_api_key

Optional AI Settings

Customize the models Ghost uses:
# Defaults shown — uncomment to override
# GHOST_MODEL=moonshotai/kimi-k2.5
# GHOST_MERGE_MODEL=google/gemini-2.5-pro-preview

# OpenAI (optional)
# OPENAPI_KEY=your_openai_api_key

Optional Features

Code Sandbox (E2B)

For sandboxed code execution:
E2B_API_KEY=your_e2b_api_key

# Custom template (optional)
# Build with: cd apps/web && npx e2b template build
# E2B_TEMPLATE=your_e2b_template_id

Background Jobs (Inngest)

INNGEST_EVENT_KEY=your_inngest_event_key
INNGEST_SIGNING_KEY=your_inngest_signing_key

Search & Memory

# Mixedbread embeddings for semantic search
MIXEDBREAD_API_KEY=your_mixedbread_api_key

# SuperMemory for AI conversation memory
SUPER_MEMORY_API_KEY=your_super_memory_api_key

Integrations

# Slack notifications
SLACK_CLIENT_ID=your_slack_client_id
SLACK_CLIENT_SECRET=your_slack_client_secret

# Vercel OIDC (for deployment auth)
VERCEL_OIDC_TOKEN=your_vercel_oidc_token

Monitoring

# Sentry error tracking
SENTRY_DSN=https://your-dsn@sentry.io/project-id
SENTRY_AUTH_TOKEN=your_sentry_auth_token

Billing (Stripe)

STRIPE_SECRET_KEY=your_stripe_secret_key
STRIPE_WEBHOOK_SECRET=your_stripe_webhook_secret
STRIPE_BASE_PRICE_ID=price_xxx
STRIPE_METERED_PRICE_ID=price_xxx

Docker Services

The docker-compose.yml configures:

PostgreSQL

postgres:
  image: postgres:16-alpine
  container_name: better-hub-postgres
  environment:
    POSTGRES_USER: postgres
    POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres}
    POSTGRES_DB: better_hub
  ports:
    - "127.0.0.1:54320:5432"

Redis with REST Proxy

redis:
  image: redis:7-alpine
  container_name: better-hub-redis

redis-rest:
  image: hiett/serverless-redis-http:latest
  container_name: better-hub-redis-rest
  ports:
    - "127.0.0.1:8079:80"
  environment:
    SRH_MODE: env
    SRH_TOKEN: ${SRH_TOKEN:-local_token}
    SRH_CONNECTION_STRING: redis://redis:6379
Data persists in Docker volumes postgres_data and redis_data. To reset, run docker compose down -v.

Development Scripts

Run from the repo root:
pnpm dev          # Start all apps in dev mode
pnpm lint         # Run oxlint
pnpm lint:fix     # Run oxlint with auto-fix
pnpm fmt          # Format with oxfmt
pnpm fmt:check    # Check formatting
pnpm typecheck    # TypeScript type checking
pnpm check        # Run lint + fmt:check + typecheck

Production Deployment

Before deploying to production:
  1. Change default passwords — Set POSTGRES_PASSWORD and SRH_TOKEN to secure values
  2. Use HTTPS — Update BETTER_AUTH_URL and NEXT_PUBLIC_APP_URL to your domain
  3. Secure secrets — Never commit .env files to version control
  4. Update OAuth callback — Change GitHub OAuth App callback URL to your production domain
For production deployments:
1

Build the application

pnpm build
2

Set production environment variables

Update .env with production values (database, Redis, domain, etc.).
3

Run migrations

cd apps/web && npx prisma migrate deploy && cd ../..
4

Start the production server

pnpm start

Troubleshooting

Database connection failed

Verify PostgreSQL is running:
docker ps | grep better-hub-postgres
Check the connection string matches your Docker setup:
DATABASE_URL=postgresql://postgres:postgres@localhost:54320/better_hub

Redis connection failed

Verify Redis REST proxy is running:
docker ps | grep better-hub-redis-rest
Ensure the token matches:
UPSTASH_REDIS_REST_TOKEN=local_token  # Must match SRH_TOKEN in docker-compose.yml

GitHub OAuth errors

Verify your OAuth App settings:
  1. Homepage URL matches BETTER_AUTH_URL
  2. Callback URL is ${BETTER_AUTH_URL}/api/auth/callback/github
  3. GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET are correct

Next Steps

Quickstart

Learn how to use Better Hub features

Contributing

Help build Better Hub — contributor guide