Self-Host Supabase Docker: Your Complete Backend in 15 Minutes
Firebase was great until you needed to own your data. Supabase gives you the same developer experience—Postgres, auth, storage, real-time—with full control. This self-host Supabase Docker guide gets you running on your own server in under 15 minutes.
What Is Supabase?
Supabase is an open-source Firebase alternative built on PostgreSQL. Self-hosting it gives you a complete backend platform without vendor lock-in or per-seat pricing.
What you get out of the box:
- PostgreSQL—the world's most trusted relational database
- Auto-generated REST and GraphQL APIs—no backend code required
- Authentication—OAuth, email/password, magic links, SSO
- Row Level Security—fine-grained access control at the database level
- Storage—S3-compatible object storage for files and images
- Realtime—WebSocket subscriptions for live data
- Edge Functions—serverless TypeScript functions
For more context on why this matters, see our take on Supabase's momentum in the developer ecosystem. If you want deeper dives, check our guides on owning your backend with Supabase and self-hosting from scratch.
Prerequisites
Before starting this self-host Supabase Docker setup, confirm you have:
Required
- A Linux server (Ubuntu 22.04+ recommended) with SSH access
- Docker Engine 24.0+ and Docker Compose v2+
- Git installed
- At least 4GB RAM (8GB+ recommended)
- 40GB SSD storage minimum (80GB+ for production)
Recommended
- 4 CPU cores for smooth multi-service operation
- A domain name pointing to your server (for HTTPS)
- Swap space (4GB+) to prevent OOM kills
Quick Server Prep
# Update system
sudo apt update && sudo apt upgrade -y
# Install Docker
sudo apt install -y docker.io docker-compose-v2 git
# Add user to docker group
sudo usermod -aG docker $USER
newgrp docker
# Verify
docker --version
docker compose version
git --version
Step 1: Get the Supabase Docker Configuration
Supabase distributes its Docker setup through the official repository. You have two options: the automated quick-start script (Linux only) or manual clone.
Option A: Quick Start Script (Linux)
# Run the automated installer
curl -fsSL https://supabase.link/setup.sh | sh
# The script will:
# - Install prerequisites (git, openssl, jq)
# - Clone the docker/ directory from the Supabase repo
# - Generate all secrets and JWT keys
# - Prompt for your URLs
# - Pull Docker images
# After it finishes, start the stack:
cd supabase-project && sh run.sh start
Option B: Manual Clone (Any OS)
# Clone the repository
git clone --depth 1 https://github.com/supabase/supabase
# Create your project directory
mkdir supabase-project
cp -rf supabase/docker/* supabase-project/
cp supabase/docker/.env.example supabase-project/.env
# Enter project directory
cd supabase-project
# Pull images
docker compose pull
Step 2: Generate Secrets and Configure URLs
Never run Supabase with default passwords. Generate secure secrets before starting.
# Generate keys and secrets
sh utils/generate-keys.sh
# Add new auth keys and asymmetric JWT signing pair
sh utils/add-new-auth-keys.sh
Now edit the .env file to set your URLs:
# Edit .env
nano .env
# Set these to your actual domain or IP:
SUPABASE_PUBLIC_URL=http://your-domain.com:8000
API_EXTERNAL_URL=http://your-domain.com:8000/auth/v1
SITE_URL=http://your-domain.com:3000
# Set a secure dashboard password (must include at least one letter)
DASHBOARD_PASSWORD=YourSecurePassword123
DASHBOARD_USERNAME=admin
Review the generated secrets in .env before proceeding. The key values you'll need for your app:
POSTGRES_PASSWORD—database passwordSUPABASE_PUBLISHABLE_KEY—client-side API keySUPABASE_SECRET_KEY—server-side API key (keep secret)
Step 3: Start the Stack
Launch all services:
# Start all services and wait for health checks
sh run.sh start
# Check status
docker compose ps
# All services should show "Up (healthy)" within a minute
If any service shows created but not Up, check logs:
# Test script for common issues
sh tests/test-container-logs.sh
# Check logs for a specific service
sh run.sh logs auth
sh run.sh logs storage
sh run.sh logs realtime
Step 4: Access the Dashboard and APIs
Once all services are healthy, access Supabase Studio:
# View your credentials anytime
sh run.sh secrets
# Studio URL: http://your-domain.com:8000
# Login with DASHBOARD_USERNAME and DASHBOARD_PASSWORD
API Endpoints
All APIs route through the Kong gateway on port 8000:
- REST API:
http://your-domain.com:8000/rest/v1/ - Auth API:
http://your-domain.com:8000/auth/v1/ - Storage API:
http://your-domain.com:8000/storage/v1/ - Realtime API:
http://your-domain.com:8000/realtime/v1/
Connect to Postgres
Use the Supavisor connection pooler:
# Session mode (direct Postgres connection)
psql 'postgres://postgres.your-tenant-id:POSTGRES_PASSWORD@your-domain:5432/postgres'
# Transaction mode (pooled)
psql 'postgres://postgres.your-tenant-id:POSTGRES_PASSWORD@your-domain:6543/postgres'
Step 5: Test Edge Functions
The default setup includes a sample function. Test it:
# Test the default hello function
curl http://your-domain.com:8000/functions/v1/hello
# Add new functions in volumes/functions//index.ts
# Then recreate the functions service:
sh run.sh recreate functions
Step 6: Secure for Production
Running on HTTP over port 8000 is fine for development. Production needs HTTPS.
Reverse Proxy with HTTPS
Place Nginx or Caddy in front of the Kong gateway. Here's a basic Nginx config:
server {
listen 80;
server_name api.yourdomain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name api.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
location / {
proxy_pass http://localhost:8000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 86400;
}
}
After setting up HTTPS, update your .env URLs to use https:// and port 443:
SUPABASE_PUBLIC_URL=https://api.yourdomain.com
API_EXTERNAL_URL=https://api.yourdomain.com/auth/v1
SITE_URL=https://app.yourdomain.com
Then recreate the services:
sh run.sh recreate
Firewall Rules
sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # HTTP (Certbot)
sudo ufw allow 443/tcp # HTTPS
sudo ufw deny 8000/tcp # Block direct Kong access
sudo ufw enable
Tips and Troubleshooting
"Service unhealthy" after startup
Check which service is failing:
docker compose ps
sh run.sh logs
# Common fixes:
# - Increase RAM/swap
# - Check that ports aren't already in use
# - Verify .env values are set correctly
Kong fails with entrypoint error
Your files may have CRLF line endings. Fix:
# Re-clone with proper line endings
git clone --depth 1 https://github.com/supabase/supabase
# Or convert existing files:
sudo apt install -y dos2unix
find . -type f -name "*.sh" -exec dos2unix {} \;
Out of memory errors
Supabase runs 10+ services. If you're resource-constrained, remove services you don't need from docker-compose.yml:
- Remove
realtimeif you don't need live subscriptions - Remove
imgproxyif you don't need image transformations - Remove
functionsif you don't use Edge Functions
Enable analytics (optional)
Logs & Analytics are disabled by default to save resources. Enable them:
sh run.sh config add logs
sh run.sh start
This adds Logflare and Vector services. Expect higher RAM usage.
Updating Supabase
# Pull latest images
sh run.sh pull
# Recreate services with new images
sh run.sh recreate
# Or update a single service:
# Edit docker-compose.yml image tag, then:
sh run.sh pull
sh run.sh recreate studio
Backup your database
# Dump the database
docker compose exec db pg_dump -U postgres postgres > backup-$(date +%Y%m%d).sql
# Backup storage volumes
docker run --rm -v supabase-project_storage:/data -v $(pwd):/backup alpine \
tar czf /backup/supabase-storage-$(date +%Y%m%d).tar.gz -C /data .
Reset everything (destructive)
# WARNING: This deletes all data
sh reset.sh
# Skip confirmation:
sh reset.sh -y
What's Next?
You now have a fully self-hosted backend platform. Here's where to go from here:
- Connect your frontend—use the Supabase client library with your
SUPABASE_PUBLIC_URLandSUPABASE_PUBLISHABLE_KEY - Set up auth providers—configure Google, GitHub, or email auth in Studio
- Enable Row Level Security—define policies to protect your data
- Create storage buckets—upload and serve files with automatic transformations
- Write Edge Functions—deploy serverless TypeScript for custom logic
- Set up backups—automate database dumps and volume snapshots
Supabase releases self-hosted updates monthly. Follow the self-hosted changelog and GitHub Discussions to stay current.
Need Help With Production Deployment?
This self-host Supabase Docker guide gets you running, but production deployments need more: HA Postgres, automated backups, monitoring, SSO configuration, and compliance hardening.
If you're building on Supabase and need infrastructure expertise, get in touch with our team. We specialize in self-hosted backend platforms that scale with your product.