The English README is canonical. See the translation policy for synchronization expectations.
SupaCloud is a next-generation, ultra-lightweight multi-tenant PaaS for self-hosting Supabase. Built on Pigsty, it enables you to run multiple isolated Supabase projects efficiently on a single server.
- Multi-Tenant Architecture: Run multiple isolated Supabase projects with shared infrastructure
- Management API: Full REST API (60+ endpoints) for complete project lifecycle management
- Web Console: Modern SvelteKit management dashboard with authentication
- Official Supabase CLI Database Workflows: The compatibility harness exercises direct
--db-urlflows includingdb push,migration list,db pull, andgen types - CLI Tools:
supacloud-clifor project users,supacloud-adminfor server operators, and optionalsupacloudctlas the local unified dispatcher - SupaCloud Pages: Frontend static site hosting with GitHub webhook auto-deploy
- Pigsty Powered: Enterprise-grade PostgreSQL with built-in monitoring (Grafana)
- One-Click Installation: Fully automated setup via
install.sh - JuiceFS Storage: Powered by PostgreSQL Large Objects (LO) for ultra-thin metadata
- Caddy Gateway: Automatic HTTPS, Admin API-driven route publishing, programmable rate limiting, security headers, and CORS
- Auto-scaling Engine: Rule-based vertical and horizontal scaling based on real-time metrics
- Bun Edge Runtime: Bun.js + Elysia Worker Pool for Edge Functions, with built-in Deno compatibility shim for legacy user code
- SSE Real-time Logs: Server-Sent Events streaming for live log tailing via
journalctl --follow - Native Queue Worker: Pure Bun.js PostgreSQL LISTEN/NOTIFY based asynchronous worker for AI inference and MQTT events
- WebSocket Task Notifications: Real-time task progress push via native Bun WebSocket
- DB Graceful Degradation: Exponential backoff retry + 503 Service Unavailable on transient DB failures
- Hardened Control Plane: Authenticated function management reads, one-time signed uploads, defensive pagination, and safe storage metadata parsing
- Edge Function Preheating: Zero cold-start via worker module pre-import on deploy
- Project OAuth/OIDC Provider: Per-project OAuth 2.1 / OIDC migration with ES256 signing keys, discovery, JWKS, authorize/token/userinfo endpoints, and OAuth client CRUD
- China OAuth: Built-in WeChat, Alipay, DingTalk login integration
- CI/CD Integration: GitHub webhook for automated deployments
- Comprehensive Tests: 400+ unit, integration, and structural regression tests
SupaCloud Lite is the Bun-native, single-project edition of SupaCloud. It runs PostgreSQL-compatible workloads in-process with PGlite and exposes the Supabase protocols used by @supabase/supabase-js: REST, Auth, Storage, Realtime, and Edge Functions. It is intended for local development, small single-project deployments, and applications that want a Docker-free Supabase-compatible backend.
Lite Auth is built into the same Bun process; it does not install or launch a GoTrue sidecar. It is enabled by default and can be disabled with [auth] enabled = false in supabase/config.toml, which turns off /auth/v1/*. Use the full platform when an independent GoTrue runtime or full GoTrue compatibility is required.
Use the full SupaCloud platform when you need multi-project tenancy, a management API or web console, shared Pigsty infrastructure, platform operations, and hosted frontend lifecycle management. Lite deliberately does not provide a multi-project control plane or Supabase Studio; each Lite process owns one project and its own state directory.
| Need | Choose |
|---|---|
| Local-first or single-project runtime without Docker | SupaCloud Lite |
| Multi-tenant platform, operator controls, or production infrastructure management | SupaCloud |
Lite requires Bun 1.3+ and keeps its default database, storage, and generated secrets under .supacloud-lite/ in the project directory. Start it with the existing Supabase CLI project layout:
bun add @supacloud/lite
bunx supacloud-lite start
bunx supacloud-lite keysThen use the printed anonymous key with the standard client:
import { createClient } from '@supabase/supabase-js'
const supabase = createClient('http://127.0.0.1:54321', process.env.SUPACLOUD_LITE_ANON_KEY!)See SupaCloud Lite documentation for CLI commands, storage/S3 configuration, compatibility limits, migration guidance, and deployment boundaries.
For persistent Lite deployments, update the pinned @supacloud/lite dependency and run supacloud-lite upgrade. The command creates a portable database/storage/secrets snapshot before applying pending migrations. snapshot create and fail-closed snapshot restore are also available for host migration and rollback preparation.
SupaCloud is best understood as a self-hosted multi-tenant control plane for Supabase-style projects, not as a clone of Supabase Cloud.
Short version:
- SupaCloud: best when you want to run many isolated projects on your own servers with a built-in operator API, web console, project lifecycle management, task queue surface, and frontend hosting.
- Supabase Cloud: best when you want a fully managed platform, hosted backups/PITR, hosted logs explorer, and hosted branching.
- Supabase Self-Hosted: best when you want the official upstream stack on your own infra and are comfortable operating Docker/services directly.
Detailed feature comparison:
┌─────────────────────────────────────────────────────────────┐
│ Management API (:9090) │
│ Bun + Elysia + TypeScript + Auto-scaling │
├─────────────────────────────────────────────────────────────┤
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ JwtService │ │ DbService │ │ StorageSvc │ │
│ └─────┬──────┘ └─────┬──────┘ └─────┬──────┘ │
│ ▼ ▼ ▼ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ GatewaySvc │ │ ScalingSvc │ │ BackupSvc │ │
│ └────────────┘ └────────────┘ └────────────┘ │
│ ▼ ▼ ▼ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ RouterSvc │ │ FrontendSv │ │ DeploySvc │ │
│ └────────────┘ └────────────┘ └────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ Shared Infrastructure │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ PostgreSQL │ │ Caddy │ │ JuiceFS │ │
│ │ (Pigsty) │ │ Gateway │ │ (PG-LO) │ │
│ └────────────┘ └────────────┘ └────────────┘ │
│ ┌────────────┐ │
│ │ Grafana │ │
│ │ (Monitor) │ │
│ └────────────┘ │
└─────────────────────────────────────────────────────────────┘
| Item | Minimum | Recommended |
|---|---|---|
| CPU | 2 cores | 4+ cores |
| RAM | 2GB | 4GB+ |
| Disk | 40GB | 100GB+ SSD |
| OS | CentOS 9, Ubuntu 22/24, Debian 12 | CentOS 9 |
Project user CLI
npm install -g @supacloud/cli
supacloud-cli status
supacloud-cli project get
supacloud-cli project logs --log_type database
supacloud-cli frontend list --ref <project-ref>supacloud-cli defaults to project context and auto-links from the current workspace .env when available.
There is no project-CLI compatibility alias named supacloud: that name is reserved for the compiled server binary at /usr/local/bin/supacloud. Use supacloudctl only for the optional local unified dispatcher.
SUPABASE_URLorSUPACLOUD_API_URLSUPABASE_SERVICE_ROLE_KEYorSUPACLOUD_API_TOKEN
AI agents should install the migration-first Skill shipped with the CLI:
supacloud-cli ai install_skill --dry_run
supacloud-cli ai install_skillServer admin CLI
npx @supacloud/admin status
npx @supacloud/admin ssh ping
npx @supacloud/admin ssh install --public_domain api.example.com --studio_domain studio.example.com
npx @supacloud/admin project create --name my-appUse supacloud-admin for installation, upgrades, tenant runtime operations, and platform-wide project lifecycle control.
One-Click Installation (Recommended)
curl -fsSL https://raw.githubusercontent.com/zuohuadong/supacloud/main/setup.sh | sudo bashThe root bootstrap itself is always fetched from the official repository. Release/API downloads try GitHub directly first and use SUPACLOUD_GITHUB_PROXY only as an explicit fallback:
curl -fsSL https://raw.githubusercontent.com/zuohuadong/supacloud/main/setup.sh \
| sudo env SUPACLOUD_GITHUB_PROXY=https://your-trusted-proxy.example bashSource/Development Installation (local artifacts only)
Production hosts should use the verified one-click setup.sh flow above. A source checkout has no Release artifacts, so build every required component first and opt into local artifact mode explicitly:
# 1. Clone repository
git clone https://github.com/zuohuadong/supacloud.git
cd supacloud
# 2. Build Management API, Edge Runtime, pgredis-runtime, Caddy, and Web Console artifacts
bun --cwd packages/management-api install
bun --cwd packages/management-api run build:linux
bun --cwd packages/edge-runtime install
bun --cwd packages/edge-runtime run build:linux
bun --cwd packages/pgredis-runtime install
bun --cwd packages/pgredis-runtime run build:linux
bun --cwd packages/web-console install --frozen-lockfile
bun --cwd packages/web-console run build
mkdir -p .local/bin dist
GOBIN="$PWD/.local/bin" go install github.com/caddyserver/xcaddy/cmd/xcaddy@v0.4.5
PATH="$PWD/.local/bin:$PATH" OUT_DIR="$PWD/dist" bash scripts/build_supacloud_caddy.sh
# 3. Configure and install from the validated local build outputs
sudo env SUPACLOUD_SETUP_ARTIFACT_MODE=local \
bash install.sh --ip 1.2.3.4 --domain api.example.com --s3 juicefs
# 4. Enable CLI
source /etc/profile.d/supacloud.shProduction Upgrades
Production servers upgrade by replacing the released Linux binary at /usr/local/bin/supacloud; they do not need to git pull application source during normal upgrades.
sudo supacloud upgrade --yesInstall and upgrade downloads are direct-first. Configure a trusted proxy only when an explicit fallback is required:
sudo SUPACLOUD_GITHUB_PROXY=https://your-trusted-proxy.example supacloud upgrade --yesRelease artifacts require same-release SHA256 verification and GitHub build provenance attestation. SUPACLOUD_ALLOW_UNVERIFIED_RELEASE=true is an emergency break-glass mode that retains SHA256 verification but must not be a normal installation setting.
Published release assets:
supacloud-linux-amd64andsupacloud-linux-arm64are the production install/upgrade binaries.supacloud-macos-amd64andsupacloud-macos-arm64are published for local development and diagnostics.
Docker Compose Self-Host (PostgreSQL 18)
cd docker/self-host
python3 init-env.py --public-url https://api.example.com --studio-url https://studio.example.com --output .env
docker compose up -d --buildThe compose stack is isolated under docker/self-host and ships a PostgreSQL 18 image with common extensions preinstalled.
For the Docker-specific Pigsty 4.4/Supabase compatibility check and backup-first upgrade path, see docs/upgrade-postgres-docker-4.4.md. Do not run the native Pigsty upgrade script against a Docker data volume.
For TrueNAS SCALE Custom App deployment of the published PostgreSQL image, see docker/self-host/TRUENAS.md.
Available CLI Options:
| Option | Description | Example |
|---|---|---|
--ip |
Server Internal IP | --ip 10.0.0.5 |
--domain |
API/Public Domain | --domain supa.com |
--studio |
Studio Dashboard Domain | --studio studio.com |
--s3 |
Storage Type | juicefs, minio, or external |
--password |
Master Password | --password mysecret |
The supacloud-cli command is project-scoped by default and is intended for deploy/build/log/database workflows around a single project:
supacloud-cli status
supacloud-cli project get
supacloud-cli project logs --log_type database
supacloud-cli project tasks
supacloud-cli database query --sql "select now()"
supacloud-cli database query --ref <ref> --file ./queries/vector-search.sql
supacloud-cli database push_migrations --ref <ref> --dir supabase/migrations --dry_run
supacloud-cli auth list_providers --ref <ref>
supacloud-cli frontend list --ref <ref>
supacloud-cli edge_functions list --ref <ref>
supacloud-cli storage list_buckets --ref <ref>For complex SQL, pgvector queries, and single-request transaction blocks, prefer --file instead of shell-escaped inline SQL.
BEGIN;
INSERT INTO audit_events(message) VALUES ('started');
INSERT INTO audit_events(message) VALUES ('finished');
COMMIT;SupaCloud supports transaction blocks inside one SQL request and wraps migrations in a transaction. It does not expose long-lived HTTP transaction sessions such as /transaction/begin and /transaction/commit; application-side long transactions should use the direct Postgres DSN with pg, postgres.js, or equivalent drivers.
pgvector example:
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE documents (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
content text NOT NULL,
embedding vector(1536)
);
CREATE INDEX documents_embedding_hnsw_idx
ON documents
USING hnsw (embedding vector_cosine_ops);
SELECT id, content
FROM documents
ORDER BY embedding <=> '[0.1,0.2,0.3]'::vector
LIMIT 5;supacloud-cli intentionally does not own platform installation, upgrades, SSH diagnostics, tenant runtime management, or destructive project lifecycle commands.
The supacloud-admin CLI is for server and platform operators:
supacloud-admin status
supacloud-admin ssh ping
supacloud-admin ssh install --public_domain api.example.com --studio_domain studio.example.com
supacloud-admin ssh diagnose
supacloud-admin project list
supacloud-admin project create --name my-app
supacloud-admin project delete --ref <ref>
supacloud-admin project pause --ref <ref>
supacloud-admin platform metricsThe REST API runs on port 9090 with Swagger documentation at /swagger.
# Create project
curl -X POST http://localhost:9090/v1/projects \
-H "Authorization: Bearer $MASTER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "My Project", "region": "local"}'
# List projects
curl http://localhost:9090/v1/projects \
-H "Authorization: Bearer $MASTER_TOKEN"
# Get API keys
curl http://localhost:9090/v1/projects/<ref>/api-keys \
-H "Authorization: Bearer $MASTER_TOKEN"Core API Endpoints:
| Method | Endpoint | Description |
|---|---|---|
| GET | /v1/projects |
List all projects |
| POST | /v1/projects |
Create project |
| GET | /v1/projects/:ref |
Get project details |
| PATCH | /v1/projects/:ref |
Update project |
| DELETE | /v1/projects/:ref |
Delete project (soft) |
| POST | /v1/projects/:ref/pause |
Pause project |
| POST | /v1/projects/:ref/restore |
Restore project |
| GET | /v1/projects/:ref/status |
Get status |
| GET | /v1/projects/:ref/health |
Get health |
| GET | /v1/projects/:ref/dashboard/summary |
Cached dashboard summary |
| POST | /v1/projects/:ref/restart |
Restart services |
| GET | /v1/projects/:ref/settings |
Get settings |
| PUT | /v1/projects/:ref/settings |
Update settings |
| GET | /v1/projects/:ref/api-keys |
Get API keys |
| POST | /v1/projects/:ref/api-keys/rotate |
Rotate legacy JWT API keys |
| POST | /v1/projects/:ref/api-keys/rotate-opaque |
Rotate Publishable/Secret keys without changing JWT sessions |
| GET | /v1/projects/:ref/auth/oauth-server |
Get project OAuth/OIDC status |
| POST | /v1/projects/:ref/auth/oauth-server/migrate |
Migrate project to OIDC signing keys |
| GET/POST/PUT/DELETE | /v1/projects/:ref/auth/oauth-clients* |
OAuth client CRUD for the project runtime |
| GET | /v1/projects/:ref/types/typescript |
Generate TS types |
| PATCH | /v1/projects/:ref/config/auth |
Configure Auth & Providers |
| GET | /v1/projects/:ref/secrets |
List Edge Function Secrets |
| POST | /v1/projects/:ref/secrets |
Upsert Secrets |
| DELETE | /v1/projects/:ref/secrets/:name |
Delete Secret |
Function management read endpoints under /v1/projects/:ref/functions* require project service-role or admin authentication. Public runtime invokes remain on /functions/v1/* and continue to use the normal Supabase function auth model.
Extended API Endpoints:
| Category | Endpoints | Description |
|---|---|---|
| Database | /v1/projects/:ref/database/* |
SQL query, schema inspection, migrations, defensive pagination |
| Auth | /v1/projects/:ref/config/auth, /v1/projects/:ref/auth/* |
OAuth providers, OAuth/OIDC Provider migration, WeChat/Alipay/DingTalk |
| Frontend | /v1/projects/:ref/frontend/* |
Pages hosting, deployments, custom domains |
| Webhook | /v1/webhooks/github |
GitHub webhook for CI/CD auto-deploy |
| Storage | /v1/storage/* |
Bucket management, file upload, one-time signed uploads, S3 migration |
| Extensions | /v1/extensions/* |
PostgreSQL extension marketplace |
| Scaling | /v1/projects/:ref/scaling/* |
Vertical upgrade & horizontal replicas |
| Backups | /v1/projects/:ref/backups/* |
Database backup & restore |
| Monitor | /v1/monitor/* |
Database monitoring & health |
| Security | /v1/security/* |
Firewall rules & SSL certificates |
| Deploy | /v1/deploy/* |
Edge Function deployment |
| Tasks | /v1/projects/:ref/tasks/* |
Background task monitoring, including lightweight summary=true list mode |
| Logs SSE | GET /v1/projects/:ref/logs/stream |
Real-time log streaming via Server-Sent Events |
| Rate Limit | GET/PUT /v1/projects/:ref/gateway/rate-limit |
Programmable per-project rate limiting (Caddy route policy) |
| Gateway Routes | GET/POST/PUT/DELETE /v1/projects/:ref/gateway/routes[/:routeId] |
Controlled custom Caddy routes (proxy, static, redirect, headers, CORS, priority) |
| WebSocket | ws://host/ws/tasks |
Real-time task progress notifications |
# Switch Edge Runtime deployment mode
./switch.sh runtime embedded # Managed by supacloud.service
./switch.sh runtime external # Standalone supacloud-edge-runtime.service
# Switch storage backend
./switch.sh storage juicefs # or: minio, external
# Show current configuration
./switch.sh statusEdge Runtime Architecture:
SupaCloud (:9090) Edge Runtime (EDGE_RUNTIME_PORT, default :9005)
├── Management API ←── supacloud.service manages by default
├── Web Console ├── Elysia Server
├── SSE Log Stream ├── Worker Thread Pool (4 threads)
├── WebSocket /ws/tasks ├── Deno Compat Shim
└── Static Assets (ETag) ├── URL Import Plugin
└── /preheat (zero cold-start)
Edge Runtime parent ── internal capability ──► pgredis-runtime (:9010)
├── per-tenant PostgreSQL pool
└── bounded L1 + LISTEN/NOTIFY
Caddy Gateway (Admin API-driven):
Automatic HTTPS, route JSON publishing, security headers, rate limiting, CORS
/api/* → :9090
/functions/* → :9090 (sdk-proxy, async enqueue + sync relay)
SupaCloud never hand-edits a Caddyfile in production. The Management API keeps the full Caddy config as JSON in memory (GatewayService), and on every route / rate-limit / cert change it:
- renders the complete Caddy JSON config,
- validates it with
caddy validate --config <tmp>, - hot-loads it via
POST /loadon the Caddy Admin API (CADDY_ADMIN_URL, defaulthttp://127.0.0.1:2019), - atomically persists the applied JSON to
CADDY_CONFIG_PATHfor reboot-time hydration, and drops aDO-NOT-EDIT.txtnext to it.
The packaged Caddyfile only enables the Admin API listener and a minimal catch-all for bootstrap; tenant routing, TLS, CORS and rate limiting are all owned by the injected JSON. GET/POST/PUT/DELETE /v1/projects/:ref/gateway/routes[/:routeId] and POST /v1/projects/:ref/gateway/config are the user-facing surface that drives these JSON updates.
Startup source differs by deployment mode: systemd installs run supacloud-caddy run --config /etc/supacloud/caddy/config.json (JSON only, no Caddyfile, with an initial JSON seeded by install.sh); the docker self-host and dev stacks boot the official caddy image with a bootstrap-only Caddyfile (admin 0.0.0.0:2019 + auto_https off + a 503 placeholder), then the Management API publishes the full JSON config via POST /load once it is healthy, retrying with backoff until Caddy is reachable. Either way the live routing config is the JSON injected through the Admin API.
Additionally, the Management API runs a periodic gateway-health.worker that polls the Caddy Admin API; when it detects a transition from unreachable back to reachable (e.g. Caddy restarted under systemd or the container restarted under docker), it triggers rebuildAllTenantConfigs() to re-publish the full route JSON so the live config stays consistent with the in-memory state, giving both deployment modes self-healing.
See docs/gateway-customization.md for the full field reference, curl examples (reverse proxy, static hosting, HTTPS upstream), rate-limit tiers, custom path rate limits, and how custom routes compose with tenant CORS.
Default installs use EDGE_RUNTIME_MODE=embedded, meaning supacloud.service starts the Bun Edge Runtime child process itself. A separate supacloud-edge-runtime.service is available for EDGE_RUNTIME_MODE=external, but you should not run both modes at the same time.
pgredis-runtime is a separate private data-plane service. The Edge parent mints a short-lived, project-scoped capability for each request; cached Worker modules only see the stable globalThis.SupaCloud.pgredis facade and never receive PostgreSQL credentials, connection pools, L1 state, or the runtime signing secret. The service is not routed by Caddy and exposes no host/container port. Its Edge v1 surface is KV/TTL only. Authenticated operators use the Web Console or Management API proxy for bounded runtime status, exact-key operations, and confirmed project-namespace flushes; browsers never call port 9010 directly. PGMQ remains the only platform queue, while Caddy remains the gateway rate limiter.
Public Edge Function traffic now enters through the Management API first:
/functions/v1/*is routed to:9090sdk-proxydecides whether the call should:- enqueue a background task and return
202 Accepted - or relay synchronously to the Bun Edge Runtime
- enqueue a background task and return
- browser and
supabase-jscallers can keep using the stockfunctions.invoke()API
This gives SupaCloud a stable control point for:
- async enqueue
- retries / timeout defaults
- idempotency
- request envelope capture
- per-function background route policy
For supabase-js compatibility, foreground invokes still use the standard:
await supabase.functions.invoke("my-function", { body: {...} })Background execution is activated through server-side function config via background_routes.
background_routes is the preferred production model for heavy paths like:
/generate/crop/generate/matting/generate/video
because it does not depend on the browser successfully forwarding custom headers.
Realtime traffic also enters through the Management API first:
/realtime/v1/websocketis routed to:9090- the Management API owns the websocket upgrade and proxies upstream Realtime traffic
- Caddy should not point browser websocket traffic directly at the Elixir Realtime container
This avoids tenant/path mismatches such as:
/realtime/v1/websocketbeing rewritten into the wrong upstream/socketpath- browser websocket requests being interpreted as the wrong tenant
If Realtime subscriptions fail after installation or migration, SupaCloud now includes one-off reconciliation commands:
cd packages/management-api
bun run realtime:reconcile
bun run realtime:reconcile-schemaUse them to:
- register any missing Realtime tenants
- repair tenant connection metadata
- grant required
realtimeschema privileges in project databases - add
public.tasksto thesupabase_realtimepublication and setREPLICA IDENTITY FULL
For new installs, install.sh now generates a valid REALTIME_DB_ENC_KEY, which prevents the historical Bad key size failure during tenant registration.
Each project keeps a dedicated PostgREST unit, but Management API now treats it as a managed runtime component with explicit desired state:
GET /v1/projects/:ref/services/postgrest/statusPOST /v1/projects/:ref/services/postgrest/start|stop|restart|pause|resume
The desired state is stored in dedicated project metadata columns (postgrest_desired, postgrest_actual, postgrest_health, and related timestamps), and the runtime reconcile worker keeps actual systemd state aligned with it. This is explicit lifecycle management, not idle auto-shrinking, so request-path performance stays unchanged.
| Feature | Current Bun Runtime |
|---|---|
| Memory (200 functions) | ~140MB |
| Cold start | < 10ms (with preheat: 0ms) |
| Warm latency | <1ms |
| Deno code compat | ✅ via shim |
| Isolation | Worker Thread |
For human operators, the CLI split is now:
@supacloud/cli/supacloud-cli: project-scoped user CLI with.envauto-link defaultssupacloudctl cli ...: unified local entrypoint. Normal dispatch is local-only and does not contact npm; usesupacloudctl check-update cliexplicitly when needed.@supacloud/admin/supacloud-admin: server and platform administration CLIsupacloudctl admin ...: unified local entrypoint with the same offline-by-default behavior; usesupacloudctl check-update adminexplicitly.- On installed servers,
/usr/local/bin/supacloudremains the compiled server binary; server upgrades still usesudo supacloud upgrade --yes.
supacloud/
├── install.sh # One-click deployment script
├── setup.sh # Remote setup bootstrap
├── switch.sh # Runtime/storage switching tool
├── supacloud # CLI management tool (shell wrapper)
├── config.env # Read-only tracked defaults template
├── packages/
│ ├── management-api/ # REST API server (Bun + Elysia)
│ │ ├── src/
│ │ │ ├── routes/ # 20 route modules (projects, auth, frontend, webhook, ws, logs, etc.)
│ │ │ ├── services/ # 20 service modules
│ │ │ ├── cli/ # CLI subcommands (lifecycle, project)
│ │ │ ├── db/ # Database layer, migrations, withRetry & graceful degradation
│ │ │ ├── middleware/ # Auth middleware
│ │ │ ├── infra/ # Health checker
│ │ │ ├── install.ts # Interactive installer
│ │ │ ├── upgrade.ts # Upgrade wizard
│ │ │ └── doctor.ts # System diagnostics
│ │ └── tests/ # Unit (17) & integration tests
│ ├── cli/ # Project user CLI
│ │ └── src/
│ ├── admin/ # Platform admin CLI
│ │ └── src/
│ ├── supacloud-lite/ # Bun + PGlite single-project Supabase-compatible runtime
│ │ └── README.md # Lite usage, migration, and compatibility guide
│ ├── edge-runtime/ # Bun Edge Functions runtime
│ │ ├── server.ts # Elysia server (EDGE_RUNTIME_PORT, default :9005) + /preheat endpoint
│ │ ├── worker-pool.ts # Fixed-size Worker Thread Pool + preheat()
│ │ ├── worker-executor.ts # Function loader + LRU cache + preheat msg
│ │ ├── deno-compat.ts # Deno API compatibility shim
│ │ ├── url-import-plugin.ts# Bun Plugin: URL import interception
│ │ └── shims/ # Deno std library replacements
│ └── web-console/ # SvelteKit management dashboard
│ └── src/ # Components, routes, assets
├── scripts/
│ └── lib/ # Shell script modules
│ ├── db_manager.sh # Database lifecycle
│ ├── gateway provider # Caddy route publishing is managed in management-api
│ ├── tenant_runtime.sh # Tenant PostgREST & GoTrue runtime
│ ├── function_manager.sh # Edge Functions management
│ ├── s3_manager.sh # Storage backend management
│ ├── jwt_manager.sh # JWT key generation
│ ├── backup_manager.sh # Backup operations
│ ├── ha_manager.sh # High availability
│ ├── security_manager.sh # Firewall & SSL
│ ├── storage_manager.sh # Storage operations
│ ├── extension_manager.sh# PostgreSQL extensions
│ ├── global_router.ts # Global routing logic
│ └── worker_runner.ts # Background worker
├── infra/
│ ├── os/ # OS-level configurations
│ └── postgres/ # PostgreSQL configurations
├── docs/ # 15 documentation files
│ ├── deploy-guide.md # Deployment guide
│ ├── architecture-multi-tenant.md # Architecture design
│ ├── china-oauth-integration.md # China OAuth (WeChat, etc.)
│ └── ... # See docs/README.md for full index
└── .github/
└── workflows/ # CI/CD (build-studio, management-api, release)
config.env is a read-only tracked defaults template. Installer-owned input is persisted at /etc/supabase/install.env; Management API runtime state is kept separately at /etc/supabase/management-api.env. Do not copy runtime state over the installation input.
Key installation settings:
| Variable | Description | Default |
|---|---|---|
SUPABASE_PUBLIC_DOMAIN |
Global API gateway domain | Production required; installer can auto-generate |
SUPABASE_STUDIO_DOMAIN |
Global console domain | Auto-derived from API domain if empty |
S3_STORAGE_TYPE |
Storage backend | juicefs |
TUS_MAX_SIZE |
Resumable upload maximum size | 524288000 (500 MiB) |
TUS_MAX_CHUNK_SIZE |
Resumable upload chunk maximum size | 16777216 (16 MiB) |
EDGE_RUNTIME |
Functions runtime | bun |
PG_VERSION |
PostgreSQL version | 18 |
PIGSTY_VERSION |
Pigsty version | v4.4.0 |
SUPACLOUD_LOGS_ENABLED |
内置采集器 + VictoriaLogs 项目日志(不使用 Logflare) | true |
SUPACLOUD_PIPELINES_ENABLED |
Pinned Supabase ETL runtime for BigQuery CDC Pipelines | true |
- Documentation Index
- Deployment Guide
- Multi-Tenant Architecture
- OAuth 2.1 / OIDC Provider
- China OAuth Integration
- Pigsty Documentation
- Supabase Self-Hosting