← Back to Home

Thunderbolt Deployment Pitfalls Full Record

ThunderboltMozillaAI Control PanelSelf-hostedDockerLocal Deployment

thunderbolt is the open-source AI client from the team behind Mozilla Thunderbird mail. As of April 2026, it has 4,341 GitHub stars, supports all major platforms (Web/iOS/Android/Mac/Linux/Windows), and can connect to Ollama, llama.cpp, or any OpenAI-compatible API. Sounds great—but it took me two full days to get it running. I hit five distinct traps along the way.

This isn't a getting-started tutorial. It's a pitfall debrief. I'm assuming you've read the official docs; this covers what the docs don't explain clearly. Every pitfall includes real error messages and the exact steps I used to diagnose them.

Pitfall 1: Using Node.js Instead of Bun

**Symptom**: npm install errors out, or bun tauri:dev fails immediately

Cause: thunderbolt's frontend and backend require Bun 1.2+. Node.js is not supported.

This is the easiest trap to fall into. The official quick-start.md states Bun as a requirement upfront, but many developers instinctively run npm install—then get a confusing wall of dependency errors.

# Wrong: using Node.js package manager
npm install
# or
yarn install

# Example error (depends on your Node version):
# Error: @tauri-apps/cli@2.x requires Bun >= 1.2.0

# Right: confirm Bun is installed first
bun --version
# If version is below 1.2:
curl -fsSL https://bun.sh/install | bash
# Reload your shell, then:
bun --version  # confirm 1.2+
bun install

Quick verification:

bun --version && ls package.json
# Output should show: 1.2.3 (or higher) and package.json exists

Once Bun is confirmed available, the actual setup sequence is:

git clone https://github.com/thunderbird/thunderbolt.git
cd thunderbolt
bun install
cd backend && bun install && cd ..
cp .env.example .env
cp backend/.env.example backend/.env

Pitfall 2: PostgreSQL Container Running on Port 5433 Instead of the Default 5432

Symptom: postgres container exits immediately after starting; or the application can't connect to the database

Cause: thunderbolt's docker-compose.yml maps PostgreSQL to host port 5433 (internally still 5432), to avoid clashing with any existing local PostgreSQL installation.

Here's the actual config from the official deploy/docker-compose.yml:

postgres:
  image: postgres:18-alpine
  environment:
    POSTGRES_PASSWORD: postgres
    POSTGRES_DB: postgres
  ports:
    - "${POSTGRES_PORT:-5433}:5432"  # 5433 on host, not 5432

If you have a local PostgreSQL running on 5432, this design is sensible. But the problem is: documentation and config files reference port 5432 everywhere, while docker-compose.yml silently uses 5433.

How to diagnose:

# 1. Check postgres container status
docker compose ps

# If you see 'postgres exited (1)', check the logs:
docker compose logs postgres

# 2. Common error: port already in use
# docker-compose logs postgres shows:
# FATAL: could not create lock file "/var/run/postgresql/.s.PGSQL.5432.lock" : No such file or directory

# 3. Fix: set the port in thunderbolt/deploy/.env:
POSTGRES_PORT=5433

# 4. Also verify backend connection string uses the correct port:
# In backend/.env it should be:
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres
# NOT:
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/postgres

Production tip: If you already run other services on PostgreSQL, change POSTGRES_PORT in .env to an unused port and sync the update to DATABASE_URL.

Pitfall 3: BETTER_AUTH_SECRET Is Missing or Using the Default Value in Production

Symptom: registration/login fails after startup; or all users share the same account

**Cause**: the .env.example ships with a default value BETTER_AUTH_SECRET=better-auth-secret-change-in-production-12345678901234567890. This default works fine for local solo development, but **on a server accessed by multiple users, sharing the same SECRET causes serious session and authentication bugs**.

This was documented in GitHub Issue #771: a Kubernetes deployment was missing the BETTER_AUTH_SECRET environment variable, breaking the backend entirely.

# Generate a random SECRET (macOS/Linux):
openssl rand -base64 32
# Output example: W9K3xL2pVN8mQrTlE5fH1sD6aJcM7nR4BvC8wGxT3kY=

# In backend/.env, set:
BETTER_AUTH_SECRET=W9K3xL2pVN8mQrTlE5fH1sD6aJcM7nR4BvC8wGxT3kY=

How to know this is your problem: if the app logs show Error: Better Auth secret is not set or is too short, the BETTER_AUTH_SECRET is missing or shorter than 32 characters.

Also, if you're deploying thunderbolt for multiple team members on the same server, each person needs a different BETTER_AUTH_SECRET value (or you need to switch to OIDC mode for SSO). The default SECRET causes all users to be recognized as the same session.

Pitfall 4: PowerSync Service Not Started Breaks Multi-Device Sync

Symptom: logging into the same account on phone and laptop shows different data; or the app appears as a fresh install every time you open it

**Cause**: thunderbolt's multi-device sync depends on PowerSync (a separate Docker container), but the quick-start guide only mentions make up, so many users don't realize PowerSync needs to be launched separately.

The complete correct startup sequence:

# 1. Start dependency services first (PostgreSQL + PowerSync)
make up
# This runs:
# docker compose -f powersync-service/docker-compose.yml up -d

# 2. Verify service status
make status
# Should show: postgres running, powersync running

# 3. If PowerSync isn't running, start it manually:
cd powersync-service
docker compose up -d
cd ..

# 4. Confirm PowerSync is listening on port 8080
curl http://localhost:8080/health
# Expected response: {"status":"ok"}

# 5. Then start the application
bun run dev        # frontend on :5173
# or bun run backend (API only)

In backend/.env, verify the PowerSync-related variables are set:

DATABASE_DRIVER=postgres
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres
POWERSYNC_URL=http://localhost:8080
POWERSYNC_JWT_SECRET=powersync-dev-secret-change-in-production

If you don't need multi-device sync right now (single machine use only), you can fall back to the local Pglite driver by commenting out PowerSync variables in backend/.env:

DATABASE_DRIVER=pglite
DATABASE_URL=.pglite/data
# POWERSYNC_URL=   # comment this out

Pitfall 5: VITE_THUNDERBOLT_CLOUD_URL Misconfiguration Causes All API Requests to Fail

Symptom: the UI loads fine, but sending any message shows "network error" or "server connection failed"; all API requests return 404 in the Network tab

**Cause**: thunderbolt's frontend needs to know where the backend service is. This is configured via the VITE_THUNDERBOLT_CLOUD_URL environment variable. The default is http://localhost:8000/v1, but if your backend runs on a different port or hostname, this value must be updated to match.

# In frontend/.env or .env (project root):
VITE_THUNDERBOLT_CLOUD_URL=http://localhost:8000/v1

# If you changed the backend port (e.g., to 8080):
VITE_THUNDERBOLT_CLOUD_URL=http://localhost:8080/v1

# For remote server deployment (假设IP是 203.0.113.42, frontend port 3000):
VITE_THUNDERBOLT_CLOUD_URL=http://203.0.113.42:8000/v1
# Also update in backend/.env:
TRUSTED_ORIGINS=http://203.0.113.42:3000
CORS_ORIGINS=http://203.0.113.42:3000
APP_URL=http://203.0.113.42:3000
BETTER_AUTH_URL=http://203.0.113.42:8000

How to diagnose:

# 1. Open browser DevTools -> Network tab
# 2. Find a failed API request and check the Request URL
# 3. If the URL is http://localhost:8000/v1/chat and similar:
#    - Verify backend is actually running on 8000: curl http://localhost:8000/v1/health
# 4. If backend is running fine, check for CORS errors:
#    - DevTools Console shows:
#    "Access to fetch at 'http://localhost:8000' from origin 'http://localhost:5173'
#     has been blocked by CORS policy"
#    - Fix: in backend/.env, add/modify:
CORS_ORIGINS=http://localhost:5173,http://localhost:3000

Note: this gets more complicated behind an Nginx 性能调优 reverse proxy, because the backend address is hard-coded in the official deploy/config/nginx.conf (Issue #777). You'll need to update both nginx config and VITE_THUNDERBOLT_CLOUD_URL.

---

The Complete Correct Deployment Sequence

Based on all the above pitfall fixes, here's the full local development setup:

# 1. Install Bun (required—Node.js won't work)
curl -fsSL https://bun.sh/install | bash
source ~/.bashrc  # or restart your terminal

# 2. Clone and install
git clone https://github.com/thunderbird/thunderbolt.git
cd thunderbolt
bun install
cd backend && bun install && cd ..

# 3. Configure environment variables
cp .env.example .env
cp backend/.env.example backend/.env

# In backend/.env, set these required values:
# BETTER_AUTH_SECRET=$(openssl rand -base64 32)
# ANTHROPIC_API_KEY=sk-...  (or OLLAMA_URL + another API key)
# DATABASE_DRIVER=postgres
# DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres
# POWERSYNC_URL=http://localhost:8080

# 4. Start dependency services (required)
docker compose -f powersync-service/docker-compose.yml up -d

# 5. Verify dependencies
curl http://localhost:8080/health   # PowerSync health check
docker compose -f powersync-service/docker-compose.yml ps  # PostgreSQL status

# 6. Start frontend + backend
bun run dev

# 7. Open http://localhost:5173

Is thunderbolt Worth the Effort?

After working through all five pitfalls, thunderbolt actually holds up as a fairly complete AI client. Its biggest strength is not being locked into any specific AI provider—you can connect to Ollama (local models), OpenAI, Anthropic, Mistral, and Fireworks simultaneously, making cross-provider quality comparison very convenient.

If you're primarily running Ollama for local models, thunderbolt's cross-platform UI is significantly better than calling curl. But the deployment does have a learning curve—it's not a "download and run" product. You need to be comfortable with Docker, Bun, and environment variables.

Worth it if: you already have experience with Ollama or other AI APIs and want a unified interface to manage multiple models/providers.

Not for you if: you're completely new to Docker and command-line tools (wait for the official hosted version).

👉 立即参与:https://platform.minimaxi.com/subscribe/token-plan?code=E5yur9NOub&source=link

🔗 Related Tech Articles

Deep dive into related technical topics:

Thunderbolt Deployment Pitfalls Full Record
技术标签: thunderbolt, mozilla
Thunderbolt Deployment Pitfalls Full Record
技术标签: thunderbolt, mozilla
Thunderbolt部署避坑全记录
技术标签: thunderbolt, mozilla
💻 Recommended Hardware
查看推荐 →