Self-Hosting Guide
basefyio is designed to be self-hosted. Deploy the entire platform with a singledocker compose up -d command. This guide covers production deployment with Traefik, Let's Encrypt SSL, and all infrastructure services.
Infrastructure Services
| Service | Image | Purpose | Default Port |
|---|---|---|---|
| database | pgvector/pgvector:pg16 | Primary database (with pgvector) | 5432 |
| auth service | quay.io/auth/auth:24.0 | Authentication (OAuth2/OIDC) | 8080 |
| Redis | redis:7-alpine | Caching, queues (BullMQ) | 6379 |
| object storage | storage/storage:latest | S3-compatible file storage | 9000/9001 |
| PgBouncer | edoburu/pgbouncer:latest | Connection pooling | 6432 |
| NoSQL Store | couchbase/server:community | Document data engine | 8091/8093/11210 |
| Traefik | traefik:v3.1 | Reverse proxy, SSL termination | 80/443 |
Application Services
| Service | Image | Purpose |
|---|---|---|
| Platform API | ghcr.io/<owner>/basefyio-api:latest | NestJS backend (port 4000) |
| Admin UI | ghcr.io/<owner>/basefyio-ui:latest | Next.js dashboard (port 3000) |
| Website | ghcr.io/<owner>/basefyio-website:latest | Marketing site + docs (port 3000) |
Quick Start (Production)
1. Clone and Configure
git clone https://github.com/your-org/basefyio.git
cd basefyio
cp .env.production.example .env.production
# Edit .env.production with your values2. Required Environment Variables
# Domain
DOMAIN=basefyio.com
ACME_EMAIL=admin@basefyio.com
# database
POSTGRES_USER=basefyio
POSTGRES_PASSWORD=<strong-random-password>
# auth service
KEYCLOAK_ADMIN_USER=admin
KEYCLOAK_ADMIN_PASSWORD=<strong-random-password>
# object storage
MINIO_ROOT_USER=basefyio
MINIO_ROOT_PASSWORD=<strong-random-password>
# NoSQL Store (Data Engine)
DATA_ENGINE_PROVIDER=nosql
NOSQL_CONNSTR=couchbase://nosql
NOSQL_USERNAME=basefyio
NOSQL_PASSWORD=<strong-random-password>
# OAuth (optional)
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
# Email (optional)
RESEND_API_KEY=
RESEND_FROM_EMAIL=noreply@basefyio.com
# Stripe (optional)
STRIPE_SECRET_KEY=
STRIPE_WEBHOOK_SECRET=3. Deploy
docker compose -f docker-compose.prod.yml --env-file .env.production up -dThis starts all services, initializes the NoSQL store (bucket, scope, collection, indexes), runs database migrations, and configures Traefik with automatic SSL certificates.
4. Verify
# Check all services are healthy
docker compose -f docker-compose.prod.yml ps
# Check the API
curl https://api.basefyio.com/health
# Check the dashboard
open https://app.basefyio.com
# Check the NoSQL store
curl -u basefyio:<password> https://localhost:8091/poolsDNS Configuration
Point these domains to your server's IP address:
| Domain | Service | Record Type |
|---|---|---|
basefyio.com | Website | A |
app.basefyio.com | Admin Dashboard | A |
api.basefyio.com | Platform API | A |
auth.basefyio.com | auth service | A |
storage.basefyio.com | object storage S3 API | A |
db.basefyio.com | PgBouncer (external) | A |
Traefik handles SSL certificates automatically via Let's Encrypt HTTP challenge.
Development Setup
# Uses docker-compose.yml (ports exposed on localhost)
docker compose up -d
# Or run individual services
docker compose up -d database auth redis storage nosql nosql-init
# Run API locally (outside Docker)
cd apps/platform-api
npm run start:dev
# Run Admin UI locally
cd apps/admin-ui
npm run devFor development without the NoSQL store, set DATA_ENGINE_PROVIDER=database in your .env — the Data Engine will use database JSONB instead.
Backup & Restore
- database — Use
pg_dumpor the project export feature in the dashboard - object storage — Use
mc mirror(object storage client) for bucket backup - auth service — Export realms via the auth service admin API or dashboard
- NoSQL store — Use the store's built-in backup tool
- Full project export — Dashboard → Backup & Export creates a ZIP with database, auth, and storage
Monitoring
- Docker health checks — All services have health checks;
docker compose psshows status - Platform API —
GET /healthreturns platform status - Data Engine —
GET /v1/projects/:id/data-engine/healthreturns NoSQL store reachability - Traefik dashboard — Available at
traefik.basefyio.com(protected by basic auth) - object storage console — Available at
storage-console.basefyio.com
Updating
# Pull latest images
docker compose -f docker-compose.prod.yml --env-file .env.production pull
# Restart with updated images
docker compose -f docker-compose.prod.yml --env-file .env.production up -d
# Database migrations run automatically on API startup (prisma db push)Troubleshooting
auth service won't start
Check database is healthy first. auth service depends on it for its database. View logs: docker compose logs auth --tail=50
Platform API depends on auth service
The API waits for auth service's health check. If auth service is stuck, the API won't start. Fix auth service first, then the API will auto-start.
NoSQL store not healthy
After cluster initialization, the health check requires authentication. The health check command tries both authenticated and unauthenticated requests. If the store was recently restarted, wait 30 seconds for warmup.
SSL certificate not issued
Traefik uses Let's Encrypt HTTP challenge. Ensure port 80 is open and DNS records point to your server. Check Traefik logs: docker compose logs traefik --tail=50