For the fastest setup, see the Quick Start.
Prerequisites
Requirements
- VPS with at least 2 GB RAM, 2 CPU cores, 20 GB storage, and a supported Linux distribution
- Domain name pointed to your VPS IP
- SSH access to your VPS
Step-by-Step VPS Setup
1. Prepare Your VPS
Connect to your VPS and install:- Docker Engine: Follow the official guide and the Post installation steps
- Node.js v24: Follow the official guide (required for the setup CLI and source installation)
2. Setup and Configure
The easiest way to get started is with the Inbox Zero CLI. You can either use it standalone or from within the cloned repo. Option A: Standalone (no clone needed).env template automatically.
Recommended choices for first-time self-hosting:
- PostgreSQL/Redis: Docker Compose
- Full stack: Yes, everything in Docker (especially when running via standalone
npx)
inbox-zero setup-google with the same flags.
The command enables required APIs, creates the Pub/Sub topic and subscription, and guides you through OAuth credential creation. It prints environment variables for you to add to your .env; it does not require a repo checkout.
You can also copy .env.example to .env and set the values yourself.
If you configure the deployment manually, set:
- Google OAuth:
GOOGLE_CLIENT_IDandGOOGLE_CLIENT_SECRET - LLM Provider: Uncomment one provider block and add your API key
- Optional: Microsoft OAuth, external Redis, etc.
GOOGLE_CLIENT_ID=skipped and GOOGLE_CLIENT_SECRET=skipped.
Note: Leave the commented connection variables at the beginning of .env.example unset when using Docker Compose. Compose supplies the correct internal hostnames automatically.
3. Deploy
Pull and start the services with your domain:ghcr.io/elie222/inbox-zero:latest and will be automatically pulled.
Important: docker compose reads NEXT_PUBLIC_BASE_URL from your shell environment or from a root .env file next to docker-compose.yml. Setting it only in apps/web/.env will not work because Compose resolves that override before the container loads apps/web/.env. If you use a custom port, set WEB_PORT the same way.
Using External Database Services (Optional)
Thedocker-compose.yml supports different deployment modes using profiles:
For external services, set the appropriate environment variables in
apps/web/.env:
- External Postgres: Set
DATABASE_URLandDIRECT_URL - External Redis: Set
UPSTASH_REDIS_URLandUPSTASH_REDIS_TOKEN
4. Check Logs
Wait for the containers to start:5. Access Your Application
Your application should now be accessible at:http://your-server-ip:3000(if accessing directly)https://yourdomain.com(if you’ve set up a reverse proxy with SSL)
Scheduled Tasks
The Docker Compose setup includes acron container that handles these scheduled tasks automatically. It runs interval loops rather than a system cron daemon, so the first request is sent when the container starts and subsequent requests use the intervals below.
The bundled Compose service does not run the two daily cleanup endpoints. Schedule
/api/cron/reasoning-retention when REASONING_RETENTION_DAYS or DRAFT_SENT_TEXT_RETENTION_DAYS is configured. Schedule /api/cron/draft-cleanup when users enable automatic cleanup of unused AI-generated drafts.
If you’re not using Docker Compose you need to set up cron jobs manually:
YOUR_CRON_SECRET with the value of CRON_SECRET from your .env file.
These endpoints accept the secret as a
GET header (Authorization: Bearer YOUR_CRON_SECRET, as above) or in a POST JSON body ({ "CRON_SECRET": "YOUR_CRON_SECRET" }).Optional: Background Job Backends
Inbox Zero supports multiple background job backends for self-hosted deployments:- QStash: best when you want a managed queue and are already using Upstash.
- BullMQ worker: best when you’re running Docker or another long-lived environment and want a local durable queue backed by Redis.
- Internal fallback: no extra services, but limited durability and throttling.
*Early access features - available on the Early Access page.
Option 1: QStash
Cost: QStash has a generous free tier and scales to zero when not in use. See QStash pricing. Add your QStash credentials to.env:
Option 2: BullMQ Worker
If you’re already running Docker Compose with Redis, you can use the built-in worker service instead of QStash:WORKER_QUEUES in your environment.
Building from Source (Optional)
If you prefer to build the image yourself instead of using the pre-built one:Auto-Join Organization
For self-hosted instances where all users should belong to a single organization, set:<YOUR_ORG_ID> with your organization’s ID from the Organization table.