Skip to main content
ProBot is a standard Next.js 14 app - anywhere that runs Node 20 will run ProBot. Vercel is the primary target because it co-locates the serverless functions for /api/* with the static assets and is free for personal use.
1

Fork and import

Fork the repo, then on Vercel pick Add New → Project and import the fork.
2

Set env vars

Add the following in Project Settings → Environment Variables:
NameExample value
DATABASE_URLpostgresql://user:pass@host:5432/probot
NEXTAUTH_SECRET<openssl rand -base64 32>
NEXTAUTH_URLhttps://probot.vercel.app (your assigned domain)
Do not set any LLM API key env vars. Keys live in user browsers.
3

Deploy

Vercel auto-detects Next.js. First deploy applies the build; runtime errors surface in Deployments → [deploy] → Functions.
4

Run migrations

Vercel doesn’t run migrations automatically. Either:
  • Locally: point DATABASE_URL at the production database in .env.local and run npm run db:migrate, or
  • Postdeploy hook: add a script that runs migrations as part of your build (advanced).
5

Verify

Hit https://<your-domain>/register, create an account, walk the bot factory.

Render, Fly.io, Railway

Same shape as Vercel - all three run Node 20 and Postgres. Build command: npm run build. Start command: npm start. Set the three env vars above.

AWS Lightsail (Node.js blueprint)

Free credit covers a year on a 1 GB instance - fine for small-scale self-hosting.
# on the Lightsail node
git clone https://github.com/vishalpatil18/probot.git
cd probot
npm ci
echo "DATABASE_URL=…" > .env.local
echo "NEXTAUTH_SECRET=…" >> .env.local
echo "NEXTAUTH_URL=https://your-domain" >> .env.local
npm run db:migrate
npm run build
pm2 start npm --name probot -- start
Use Lightsail’s load balancer + cert manager for TLS, or front it with Nginx.

Docker

One-command self-host is tracked for Stage 7 (see Roadmap). Until then, here’s a minimal Dockerfile shape:
Dockerfile
FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci

FROM node:20-alpine AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

FROM node:20-alpine AS runtime
WORKDIR /app
ENV NODE_ENV=production
COPY --from=build /app/.next ./.next
COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/package.json ./package.json
COPY --from=build /app/public ./public
COPY --from=build /app/drizzle ./drizzle
EXPOSE 3000
CMD ["npm", "start"]
Pair with docker-compose.yml that wires postgres:16 alongside.

Database choices

Any Postgres 13+ works (needs gen_random_uuid(), available via pgcrypto).
HostFree tier?Notes
SupabaseYes - 2 free projects, 500MB eachRecommended. Same Postgres you can self-host locally.
NeonYes - generous free tierBranch-per-deploy is nice for previews.
Render PGYes - small free tier
Local DockerFreepostgres:16 works; not for production traffic.

Environment variables reference

Required:
VariablePurpose
DATABASE_URLPostgres connection string; used by Drizzle + pg.Pool
NEXTAUTH_SECRETJWT signing secret for NextAuth. Generate with openssl rand -base64 32
NEXTAUTH_URLCanonical URL for callback construction (e.g. https://probot.vercel.app)
Forbidden - do not set:
  • ANTHROPIC_API_KEY / OPENAI_API_KEY / AZURE_OPENAI_KEY. ProBot is BYO-key; setting these server-side defeats the whole model. The key path explicitly reads x-llm-api-key from the request header and does not fall back to env.

Troubleshooting

npm run db:migrate fails with “function gen_random_uuid() does not exist”

Your Postgres is missing pgcrypto. Run as a superuser:
CREATE EXTENSION IF NOT EXISTS pgcrypto;

NextAuth redirect loop

NEXTAUTH_URL doesn’t match the host the browser is actually using. Set it to the exact origin (no trailing slash).

Chat returns 502 provider_unavailable

The provider rejected the request. Check the browser network tab for the response body - invalid_llm_key means the pasted key was wrong; provider_unavailable with no further detail usually means the provider is down or the model id is wrong.

Tests fail locally

npm run test
should print 260 passing. If anything fails, file an issue with the full output - see CONTRIBUTING.md.