Self-Hosting Guide
Run VibeBasket on your own infrastructure with the single-node deployment shape the product is currently optimized for: one app process, one SQLite database, optional OAuth, and optional encrypted backup storage.
Docker (recommended)
The easiest way to self-host VibeBasket. The image is a lean multi-stage build based on Node.js 22 Alpine. The SQLite database file is persisted through a named Docker volume so your data survives container restarts and upgrades.
Step 1 — Clone & configure
git clone https://github.com/mhmtayberk/VibeBasket.git cd VibeBasket # Copy the example env file and fill in your values cp .env.example .env
Step 2 — Start with Docker Compose
docker compose up -d # View logs docker compose logs -f web
Step 3 — Seed the catalog
# Run the catalog sync inside the running container docker compose exec web node scripts/catalog-sync.mjs
Upgrading
git pull docker compose up -d --build
Helm (Kubernetes)
A fully-featured Helm chart is available in charts/vibebasket/. The chart deploys a single-replica Deployment with a ClusterIP Service, optional Ingress, and a PersistentVolumeClaim for the SQLite database. Non-secret runtime values belong under .Values.env, while secrets such as AUTH_SECRET and OAuth client secrets belong under .Values.secretEnv or an existing Kubernetes Secret.
git clone https://github.com/mhmtayberk/VibeBasket.git cd VibeBasket helm install vibebasket ./charts/vibebasket \ --set env.NEXTAUTH_URL=https://vibebasket.example.com \ --set secretEnv.AUTH_SECRET=$(openssl rand -base64 32) \ --set env.AUTH_GITHUB_ID=your-client-id \ --set secretEnv.AUTH_GITHUB_SECRET=your-client-secret \ --set env.AUTH_GITHUB_ENABLED=true \ --set persistence.size=5Gi # Or install with a custom values file helm install vibebasket ./charts/vibebasket -f my-values.yaml
Manual Installation
Requires Node.js >=20 and pnpm >=9. Suitable for VMs, bare-metal servers, or platforms that do not run Docker.
git clone https://github.com/mhmtayberk/VibeBasket.git && cd VibeBasket cp .env.example .env # fill in values (see below) pnpm install --frozen-lockfile pnpm run build node scripts/catalog-sync.mjs # seed the database pnpm --filter web start # production server on :3000
Environment Variables
OAuth Callback URLs
When enabling OAuth authentication, configure the exact redirect callback URL in each provider's developer console:
${NEXTAUTH_URL}/api/auth/callback/github${NEXTAUTH_URL}/api/auth/callback/google${NEXTAUTH_URL}/api/auth/callback/apple${NEXTAUTH_URL}/api/auth/callback/microsoft-entra-idFor local development, replace ${NEXTAUTH_URL} with http://localhost:3000.
Never commit your .env file. The .env .gitignore. In Docker deployments, pass secrets as environment variables or use Docker secrets.
If you run VibeBasket behind Cloudflare, keep application security headers enabled and disable script-injecting edge features for this site unless you explicitly plan for them. In practice that means turning off Browser Insights, Rocket Loader, and Speed Brain / speculative prefetch features that inject inline or third-party scripts, otherwise the site will log CSP violations by design.
| Variable | Required | Description |
|---|---|---|
| DATABASE_URL | Required | SQLite connection string. Use file:/data/vibebasket.db for Docker (volume mount) or an absolute path for manual installs. |
| AUTH_SECRET | Required | Random 32-byte secret used to sign Next-Auth session tokens. Generate with: openssl rand -base64 32 |
| NEXTAUTH_URL | Required | The public canonical URL of your deployment, e.g. https://vibebasket.example.com. Required for OAuth redirects. |
| AUTH_TRUST_HOST | Optional | Set to true when running behind a reverse proxy such as Coolify, Nginx, or Cloudflare. Strongly recommended for production OAuth callback reliability. |
| AUTH_GITHUB_ID / SECRET | Optional | GitHub OAuth App credentials. Set AUTH_GITHUB_ENABLED=true to enable. |
| AUTH_GOOGLE_ID / SECRET | Optional | Google OAuth credentials. Set AUTH_GOOGLE_ENABLED=true to enable. |
| AUTH_APPLE_ID / SECRET | Optional | Apple Sign-In credentials. Set AUTH_APPLE_ENABLED=true to enable. |
| AUTH_MICROSOFT_ENTRA_ID_ID / SECRET | Optional | Microsoft Entra ID (Azure AD) credentials. Set AUTH_MICROSOFT_ENTRA_ID_ENABLED=true. Uses /common/ endpoint by default. |
| ADMIN_OAUTH_EMAILS | Optional | Comma-separated list of admin emails. Access is granted only when the OAuth account email is allowlisted and verified. |
| TRUST_PROXY | Optional | Set to true when running behind Cloudflare, Nginx, or another trusted reverse proxy. Proxy IP headers are ignored otherwise. |
| CATALOG_REFRESH_TOKEN | Optional | Optional token required for authenticated production callers that use /api/catalog?refresh=1. |
| BACKUP_STORAGE_BACKEND | Optional | Backup storage backend: local, s3, r2, spaces, azure, or gcs. Defaults to local. Can also be set via admin panel. |
| BACKUP_S3_* / R2_* / SPACES_* | Optional | S3-compatible storage credentials (endpoint, region, bucket, access key, secret key). Covers AWS S3, Cloudflare R2, and DigitalOcean Spaces. |
| BACKUP_AZURE_CONNECTION_STRING / CONTAINER | Optional | Azure Blob Storage connection string and container name. |
| BACKUP_GCS_BUCKET / PROJECT_ID | Optional | Google Cloud Storage bucket name and GCP project ID. |
Bundle TTL & Cleanup
Anonymous bundles expire after 48 hours. Registered user bundles persist for 365 days. The platform periodically purges expired bundles and stale session tokens. Administrators can trigger a manual force cleanup from the admin dashboard under System Health.
Admin Dashboard
The admin panel at /admin provides catalog sync controls, backup management, FTS5 index health checks, database integrity diagnostics, force cleanup utilities, user overview telemetry, and admin email configuration. Access is gated by the ADMIN_OAUTH_EMAILS environment variable.
Helm Deployment
A Helm chart is available at charts/vibebasket/ for Kubernetes deployments. The chart includes a Deployment, Service, Ingress, and PersistentVolumeClaim for SQLite storage.
The deployment uses strategy: Recreate to prevent SQLite corruption during updates. Pod securityContext runs as non-root user 1001 with all capabilities dropped. Production secrets should use existingSecret instead of embedding credentials in values.
Before exposing a public domain, walk through the repository's production readiness checklist in docs/PRODUCTION_READINESS_CHECKLIST.md.
SQLite WAL Mode
VibeBasket enables SQLite WAL (Write-Ahead Logging) mode on startup. This allows concurrent reads during writes and is required for the catalog sync process. Do not mount the database file on a network filesystem (NFS, CIFS) because WAL locking relies on local OS primitives. If you run multiple Node.js replicas, use a load balancer that routes all writes to a single instance, or migrate to a Turso remote database.