Skip to content

qubitquilt/SupaControl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

SupaControl

GitHub Actions Codecov Go Report Card License: MIT

Built With

Go React Vite NodeJS NPM Kubernetes Docker Helm Postgres GitHub Actions


SupaControl is a self-hosted management platform for orchestrating multi-tenant Supabase instances on Kubernetes. It provides a robust API and web dashboard for automated provisioning, monitoring, and lifecycle management of Supabase deployments.

Perfect for:

  • 🏒 SaaS Providers offering Supabase as a managed service
  • πŸ‘¨β€πŸ’» Development Teams managing multiple environments
  • πŸŽ“ Educational Institutions providing isolated instances for students
  • πŸ—οΈ Platform Engineers building internal developer platforms

Table of Contents

Overview

SupaControl acts as a control plane that sits between you and your Kubernetes cluster, simplifying the complexity of managing multiple Supabase instances.

What It Does

  • πŸš€ Automates Supabase instance deployment using Helm charts
  • πŸ”’ Isolates each instance in its own Kubernetes namespace
  • πŸ“Š Manages complete instance lifecycle (create, monitor, delete)
  • πŸ” Secures API access with JWT authentication and API keys
  • 🌐 Provides a modern web dashboard for visual management
  • πŸ› οΈ Integrates with CI/CD pipelines via REST API

Why SupaControl?

Without SupaControl:

# Manual Supabase deployment
helm repo add supabase https://...
kubectl create namespace supa-myapp
helm install myapp supabase/supabase -n supa-myapp -f custom-values.yaml
kubectl apply -f ingress.yaml -n supa-myapp
# Repeat for each instance... πŸ˜“

With SupaControl:

# One command deployment
supactl create myapp

# Or via API
curl -X POST https://supacontrol.example.com/api/v1/instances \
  -H "Authorization: Bearer $API_KEY" \
  -d '{"name": "myapp"}'

Features

Core Features

  • πŸš€ Automated Provisioning: Deploy complete Supabase stacks with a single API call
  • πŸ”’ Complete Isolation: Each instance in its own dedicated Kubernetes namespace
  • πŸ” Security First: API key and JWT authentication, encrypted secrets management
  • πŸ“Š Persistent Inventory: PostgreSQL for users and API keys only; instance state managed via Kubernetes CRDs. See ADR 001 for details.
  • ⏳ Asynchronous Operations: Instance creation and deletion are asynchronous; poll GET /api/v1/instances/:name for status updates.
  • 🌐 Web Dashboard: Modern React-based UI for instance management
  • πŸ”‘ API Key Management: Generate, list, and revoke keys for CLI/programmatic access
  • 🎯 Status Monitoring: Real-time instance health and deployment status
  • πŸ—‘οΈ Clean Deletion: Automated cleanup of namespaces and resources

Technical Highlights

  • API-First Design: Complete functionality exposed via REST API
  • Kubernetes-Native: Built on client-go and Helm v3 SDK
  • Stateless Application: Horizontally scalable for high availability
  • Declarative Orchestration: Kubernetes resources managed declaratively
  • Multi-Tenant Ready: Designed for managing dozens to hundreds of instances
  • Production-Ready: Includes health checks, logging, and error handling
  • CI/CD Friendly: Integrate with automated deployment pipelines

Use Cases

SaaS Multi-Tenancy

Customer A β†’ Instance: supa-customer-a (dedicated database, isolated)
Customer B β†’ Instance: supa-customer-b (dedicated database, isolated)
Customer C β†’ Instance: supa-customer-c (dedicated database, isolated)

Development Environments

Production  β†’ Instance: supa-prod
Staging     β†’ Instance: supa-staging
Development β†’ Instance: supa-dev
Testing     β†’ Instance: supa-test

Educational Institutions

Student 1 β†’ Instance: supa-student1 (isolated learning environment)
Student 2 β†’ Instance: supa-student2 (isolated learning environment)
...

Architecture

High-Level Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      SupaControl                         β”‚
β”‚                   (Control Plane)                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                          β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                  β”‚
β”‚  β”‚  Web UI      β”‚    β”‚  REST API    β”‚                  β”‚
β”‚  β”‚  (React)     │◄────  (Echo/Go)   │◄─── API Clients β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜                  β”‚
β”‚                              β”‚                           β”‚
β”‚                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”               β”‚
β”‚                    β”‚   Orchestrator     β”‚               β”‚
β”‚                    β”‚   (K8s + Helm)     β”‚               β”‚
β”‚                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜               β”‚
β”‚                              β”‚                           β”‚
β”‚                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”               β”‚
β”‚                    β”‚  Inventory DB      β”‚               β”‚
β”‚                    β”‚  (PostgreSQL)      β”‚               β”‚
β”‚                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                               β”‚
                      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                      β”‚  Kubernetes API    β”‚
                      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                β”‚
          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
          β”‚                     β”‚                     β”‚
     β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”           β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”           β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”
     β”‚Instance1β”‚           β”‚Instance2β”‚           β”‚Instance3β”‚
     β”‚Namespaceβ”‚           β”‚Namespaceβ”‚           β”‚Namespaceβ”‚
     β”‚supa-app1β”‚           β”‚supa-app2β”‚           β”‚supa-app3β”‚
     β”‚         β”‚           β”‚         β”‚           β”‚         β”‚
     β”‚ Supabaseβ”‚           β”‚ Supabaseβ”‚           β”‚ Supabaseβ”‚
     β”‚  Stack  β”‚           β”‚  Stack  β”‚           β”‚  Stack  β”‚
     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

For detailed architecture documentation, see ARCHITECTURE.md.

Instance State Management

SupaControl uses Kubernetes Custom Resource Definitions (CRDs) as the single source of truth for instance state. The SupabaseInstance CRD tracks the desired and actual state of each Supabase deployment, enabling declarative management and reconciliation.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   SupabaseInstance CRD   β”‚
β”‚     (Desired State)      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
          β”‚ Watches
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Controller       β”‚
β”‚   (Reconciles)     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
          β”‚ Creates/Manages
          β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Supabase Stack  β”‚
β”‚ (Actual State)   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

See ADR 001 for the rationale behind using CRDs.

Quick Start

The fastest way to get started with SupaControl is using our interactive installer.

Note: Currently requires git clone as no npx installer is available.

Prerequisites Checklist

Before you begin, ensure you have:

  • βœ… Kubernetes Cluster (v1.24+) running and accessible
  • βœ… kubectl installed and configured
  • βœ… Helm (v3.13+) installed
  • βœ… Ingress Controller (e.g., nginx-ingress) deployed in your cluster
  • ⚠️ DNS/Domain configured for accessing the dashboard

Quick Prerequisites Check:

# Verify kubectl
kubectl version --client

# Verify Helm
helm version

# Verify cluster access
kubectl cluster-info

# Verify ingress controller
kubectl get ingressclass

5-Minute Install

# 1. Clone the repository
git clone https://github.com/qubitquilt/SupaControl.git
cd SupaControl/cli

# 2. Install dependencies
npm install

# 3. Run interactive installer
npm start

The installer will:

  1. βœ… Check all prerequisites
  2. πŸ” Generate secure secrets automatically
  3. πŸ“ Guide you through configuration (domain, ingress, etc.)
  4. πŸš€ Deploy to your Kubernetes cluster
  5. πŸ“‹ Provide access information and next steps

After installation completes:

# 1. Wait for pods to be ready (1-2 minutes)
kubectl get pods -n supacontrol --watch

# 2. Access the dashboard
# Navigate to https://supacontrol.yourdomain.com

# 3. Login with default credentials
# Username: admin
# Password: admin
# ⚠️ CHANGE THIS IMMEDIATELY!

First Steps After Install

# 1. Access dashboard and change default password
# Go to Settings β†’ Change Password

# 2. Generate an API key for CLI access
# Go to Settings β†’ API Keys β†’ Create New Key

# 3. Install the CLI tool
curl -sSL https://raw.githubusercontent.com/qubitquilt/supactl/main/scripts/install.sh | bash

# 4. Login to SupaControl
supactl login https://supacontrol.yourdomain.com

# 5. Create your first Supabase instance
supactl create my-first-app

# 6. Check instance status
supactl status my-first-app

# 7. List all instances
supactl list

Installation

Option 1: Interactive Installer (Recommended)

The easiest way to install SupaControl. See Quick Start above.

Full CLI installer documentation: cli/README.md

Option 2: Manual Helm Installation

For advanced users who want full control over the installation.

# 1. Clone repository
git clone https://github.com/qubitquilt/SupaControl.git
cd SupaControl

# 2. Create values.yaml
cat > values.yaml <<EOF
config:
  jwtSecret: "your-very-long-and-secure-jwt-secret-here-change-this"
  database:
    host: "supacontrol-postgresql"
    port: "5432"
    user: "supacontrol"
    password: "your-secure-db-password-here-change-this"
    name: "supacontrol"
  kubernetes:
    ingressClass: "nginx"
    ingressDomain: "supabase.yourdomain.com"

ingress:
  enabled: true
  className: "nginx"
  hosts:
    - host: supacontrol.yourdomain.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: supacontrol-tls
      hosts:
        - supacontrol.yourdomain.com

postgresql:
  enabled: true
  auth:
    password: "your-secure-postgres-password-here"
    database: "supacontrol"
    username: "supacontrol"
EOF

# 3. Install with Helm
kubectl create namespace supacontrol
helm install supacontrol ./charts/supacontrol \
  -f values.yaml \
  -n supacontrol

# 4. Watch deployment
kubectl get pods -n supacontrol --watch

Option 3: Development Mode

For local development without Kubernetes:

Before running, ensure KUBECONFIG is set for local Kubernetes development. See docs/DEVELOPMENT.md for detailed setup instructions and troubleshooting.

# 1. Start PostgreSQL
docker run --name supacontrol-postgres \
  -e POSTGRES_USER=supacontrol \
  -e POSTGRES_PASSWORD=password \
  -e POSTGRES_DB=supacontrol \
  -p 5432:5432 \
  -d postgres:14

# 2. Set environment variables
export DB_HOST=localhost DB_PORT=5432
export DB_USER=supacontrol DB_PASSWORD=password DB_NAME=supacontrol
export JWT_SECRET=your-dev-jwt-secret-at-least-32-chars

# 3. Run backend
cd server && go run main.go

# 4. Run frontend (in another terminal)
cd ui && npm install && npm run dev

Usage

Web Dashboard

Access the dashboard at https://supacontrol.yourdomain.com

Dashboard Features:

  • πŸ“Š Instance Overview - List all Supabase instances with status
  • βž• Create Instances - Deploy new instances with one click
  • πŸ—‘οΈ Delete Instances - Remove instances and clean up resources
  • πŸ”‘ API Key Management - Generate and revoke API keys
  • πŸ‘€ User Settings - Change password and manage account

API Usage

All API endpoints require authentication except /healthz and /api/v1/auth/login.

Quick Example:

# 1. Login
TOKEN=$(curl -X POST https://supacontrol.example.com/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"admin"}' | jq -r '.token')

# 2. Create instance
curl -X POST https://supacontrol.example.com/api/v1/instances \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"my-app"}'

# Note: Instance creation is asynchronous. Poll for status:
curl -X GET https://supacontrol.example.com/api/v1/instances/my-app \
  -H "Authorization: Bearer $TOKEN"

# 3. List instances
curl -X GET https://supacontrol.example.com/api/v1/instances \
  -H "Authorization: Bearer $TOKEN"

Complete API documentation: docs/API.md

Configuration

Environment Variables

Variable Description Default Required
SERVER_PORT HTTP server port 8091 No
DB_HOST PostgreSQL host localhost Yes
DB_PORT PostgreSQL port 5432 Yes
DB_USER Database username supacontrol Yes
DB_PASSWORD Database password - Yes
DB_NAME Database name supacontrol Yes
JWT_SECRET JWT signing secret - Yes
KUBECONFIG Path to kubeconfig Empty (in-cluster) No
DEFAULT_INGRESS_CLASS Ingress class nginx No
DEFAULT_INGRESS_DOMAIN Base domain for instances supabase.example.com No

Note for Developers: The KUBECONFIG environment variable is crucial for local Kubernetes development. See the Development Guide for detailed setup instructions and troubleshooting.

For complete configuration options, see the Helm chart values.

Documentation

Comprehensive documentation is available in the /docs directory:

Getting Started

  • πŸ“˜ README.md (this file) - Overview and quick start
  • πŸš€ cli/README.md - CLI installer documentation

Technical Documentation

Contributing

CLI Tool

The project's cli/ directory contains the interactive installer for SupaControl. For the full supactl CLI tool, see https://github.com/qubitquilt/supactl. Features like local mode are available in the external repository.

Installation

# Linux/macOS
curl -sSL https://raw.githubusercontent.com/qubitquilt/supactl/main/scripts/install.sh | bash

# Or download from releases
# https://github.com/qubitquilt/supactl/releases

Quick Start

# Login to SupaControl server
supactl login https://supacontrol.yourdomain.com

# Create instance
supactl create my-project

# List instances
supactl list

# Check instance status
supactl status my-project

# Delete instance
supactl delete my-project

Features

  • πŸš€ Single binary - No dependencies, works everywhere
  • πŸ” Secure auth - Credential management built-in
  • πŸ“‚ Directory linking - Associate local dirs with instances
  • 🎨 Interactive UI - Beautiful prompts and progress indicators
  • 🐳 Local mode - Manage Docker-based instances without a server

Full CLI documentation: github.com/qubitquilt/supactl

Roadmap

Planned Features

v0.2.0

  • Instance update/upgrade support
  • Custom resource limits per instance
  • Instance status webhooks
  • Backup and restore functionality

v0.3.0

  • Prometheus metrics integration
  • Grafana dashboards
  • Instance templates/presets
  • Multi-cluster support

v0.4.0

  • Cost tracking per instance
  • Resource quota management
  • Advanced RBAC (user roles)
  • Audit logging

Future

  • GitOps integration (ArgoCD/Flux)
  • Instance cloning
  • Automated scaling policies
  • Multi-tenancy improvements
  • Custom domain per instance
  • Instance migration between clusters

Contributing to Roadmap

Have ideas? We'd love to hear them!

  • πŸ’‘ Open a feature request
  • πŸ—³οΈ Vote on existing feature requests
  • πŸ’¬ Join discussions on GitHub

Contributing

We welcome contributions! Whether you're fixing bugs, improving documentation, or proposing new features, we appreciate your help.

Quick Start

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Make your changes
  4. Test: make test
  5. Commit: git commit -m 'feat: add amazing feature'
  6. Push: git push origin feature/amazing-feature
  7. Open a Pull Request

Ways to Contribute

  • πŸ§ͺ Testing - Improve test coverage (currently ~6%). See TESTING.md for details.
  • πŸ“ Documentation - Tutorials, guides, examples
  • πŸ› Bug Fixes - Fix reported issues
  • ✨ Features - Implement roadmap items
  • 🎨 UI/UX - Improve dashboard design
  • πŸ”’ Security - Security audits and improvements

See CONTRIBUTING.md for detailed guidelines.

License

MIT License - See LICENSE.md for details.

Copyright (c) 2024 SupaControl Contributors

Support

Documentation

Community

Related Projects

Acknowledgments

SupaControl is built on excellent open-source projects:

  • Supabase - The open source Firebase alternative
  • supabase-kubernetes - Community Helm chart
  • Kubernetes - Container orchestration platform
  • Helm - The package manager for Kubernetes
  • Echo - High performance Go web framework
  • React - JavaScript library for user interfaces
  • Vite - Next generation frontend tooling
  • client-go - Go client for Kubernetes
  • sqlx - Extensions to Go's database/sql

Special thanks to all contributors!


SupaControl - Self-hosted Supabase management, simplified.

Get Started Β· Documentation Β· Report Bug Β· Request Feature

Made with ❀️ by the SupaControl community

About

No description, website, or topics provided.

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •