External Supabase (BYO data plane)

The default self-host bundle includes Supabase OSS — Postgres, GoTrue, PostgREST, Realtime, Storage, Kong. If you already operate Supabase elsewhere (hosted Supabase Cloud, managed Postgres + the Supabase services on Kubernetes, a separate VM), you can point this stack at it and skip the bundled containers entirely.

When to BYO

  • You already have a managed Postgres with backups + monitoring you trust more than what this bundle ships.
  • You're consolidating multiple apps on one Supabase project (CCD- Suite is one of many).
  • You're running at a scale where bundled single-node Postgres is going to bottleneck.
  • You're on hosted Supabase Cloud and want to keep using their dashboard / branching / point-in-time recovery.

How

1. Comment out the bundled Supabase services

In your install dir's docker-compose.yml, comment out (or delete) the following services:

# db:
# auth:
# rest:
# realtime:
# storage:
# kong:
# db-migrate:

Also remove their depends_on references from the four CCD app services (web, api-gateway, ai-services, worker):

web:
  depends_on:
    # db-migrate:    ← remove
    #   condition: service_completed_successfully
    # kong:          ← remove
    #   condition: service_started
    ollama:
      condition: service_healthy

2. Point at your external Supabase

In .env:

# All three URLs point at your external Supabase API gateway
# (the host that fronts GoTrue/PostgREST/Realtime/Storage).
SUPABASE_URL=https://api.your-supabase.example.com
NEXT_PUBLIC_SUPABASE_URL=https://api.your-supabase.example.com
SUPABASE_PUBLIC_URL=https://api.your-supabase.example.com

# Keys from your Supabase project's API settings.
SUPABASE_ANON_KEY=eyJhbGciOi...
SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOi...
SUPABASE_JWT_SECRET=<the JWT secret from your project>

If you're on hosted Supabase Cloud:

  • SUPABASE_URL = https://<project-ref>.supabase.co
  • SUPABASE_ANON_KEY = the anon public key from Project Settings → API
  • SUPABASE_SERVICE_ROLE_KEY = the service_role secret key from the same page
  • SUPABASE_JWT_SECRET = JWT Settings → JWT Secret

3. Run migrations against the external DB

The bundled stack runs db-migrate automatically. With BYO, you run the migrations once, before first boot:

# The migration files ship inside your self-host bundle — no source
# checkout needed. Work from your install directory:
cd ~/ccd

# Hosted Supabase Cloud
supabase link --project-ref <your-ref>
supabase db push

# Self-hosted Supabase / managed Postgres — use the bundled migrator
# instead, pointing at your external DB:
export PGHOST=<host> PGPORT=5432 PGUSER=postgres PGPASSWORD=<...> PGDATABASE=postgres
docker compose run --rm db-migrate

(The db-migrate compose service is an idempotent psql runner — the same one the bundle uses internally — that tracks applied migrations in a _ccd_migrations ledger table.)

4. Start the slim stack

cd <your-install-dir>
docker compose up -d

Only ollama, ollama-preload, and the four CCD app services start. The data plane lives at your external Supabase.

Caveats

  • pg_cron — some CCD background jobs use Postgres cron via pg_cron. Hosted Supabase enables pg_cron on request; self-hosted Supabase has it built into the supabase/postgres image. If your external Postgres doesn't have pg_cron, those jobs fall back to the worker's BullMQ scheduler (less efficient but functional).

  • pgvector dimensions — the knowledge-graph embedding column is vector(1536) to match cloud's text-embedding-3-small. If you're on a different embedding model (768-dim Ollama default, 1024-dim mxbai), semantic search falls through to pg_trgm fuzzy matching. See Hardware sizing for the dimension contract.

  • Realtime — if your external Supabase has Realtime disabled, the CCD UI's realtime layer falls back to polling. UI still works, feels less live.

  • Storage — bucket policies are CCD-Suite's responsibility. The migrations create the buckets we need; you don't need to bootstrap them by hand.

Hybrid: external Postgres only, bundled Supabase services

A middle ground: keep the bundled auth/rest/realtime/storage/ kong services but point them at an external Postgres. Edit each service's DB_* env vars in docker-compose.yml to your external host. The db-migrate sidecar still runs against the external DB.

Useful when you want managed Postgres (RDS, Cloud SQL, etc.) without running your own Supabase application layer.