Self-hosting Supabase gives you complete control over your data, eliminates vendor lock-in, and can dramatically reduce costs at scale. But getting from zero to a production-ready deployment involves more than just running docker compose up. This guide walks you through the entire process—from server requirements to SSL certificates—so you can deploy Supabase on your own infrastructure with confidence.
Why Self-Host Supabase?
Before diving into the technical steps, let's be clear about when self-hosting makes sense:
Self-hosting is ideal when you:
- Need full control over your data for compliance (GDPR, HIPAA, SOC 2)
- Want to avoid the $25/month base plus $10/project pricing of Supabase Cloud
- Have projects that would pause on the free tier due to inactivity
- Require specific geographic data residency
- Want to run Supabase in an air-gapped or isolated environment
Self-hosting might not be for you if:
- You don't want to manage infrastructure, updates, and backups
- You need automatic scaling without manual intervention
- You want access to the latest features immediately (self-hosted can lag behind)
For a detailed breakdown of the trade-offs, check out our Supabase Self-Hosted vs Cloud comparison.
Prerequisites
Before you start, ensure you have:
Server Requirements
Supabase runs multiple services (PostgreSQL, GoTrue Auth, PostgREST, Realtime, Storage, and more), so adequate resources are essential:
| Specification | Minimum | Recommended |
|---|---|---|
| RAM | 4GB | 8GB+ |
| CPU | 2 cores | 4+ cores |
| Storage | 50GB SSD | 80GB+ NVMe SSD |
| OS | Ubuntu 20.04+ | Ubuntu 22.04 LTS |
For small to medium production workloads, a VPS with 8GB RAM and 4 vCPUs provides comfortable headroom. You can run leaner by disabling services you don't need—more on that later.
Software Requirements
- Docker (version 20.10+)
- Docker Compose (version 2.0+)
- Git
- A domain name (for SSL and proper API access)
- Basic familiarity with the Linux command line
Cost Comparison
Here's what self-hosting costs look like in practice:
| Provider | Specs | Monthly Cost |
|---|---|---|
| Hetzner | 8 vCPU, 32GB RAM | ~$50 |
| DigitalOcean | 8 vCPU, 16GB RAM | ~$96 |
| Vultr | 6 vCPU, 16GB RAM | ~$80 |
| Supabase Cloud | Similar performance | ~$410+ |
The savings become significant when running multiple projects, since self-hosted has no per-project fees.
Step 1: Prepare Your Server
SSH into your fresh Ubuntu server and update packages:
sudo apt update && sudo apt upgrade -y
Install Docker
Supabase uses Docker containers for all its services. Install Docker with the official convenience script:
curl -fsSL https://get.docker.com -o get-docker.sh sh get-docker.sh
Add your user to the docker group to avoid using sudo for every command:
sudo usermod -aG docker $USER newgrp docker
Verify the installation:
docker --version docker compose version
Install Git
sudo apt install git -y
Step 2: Clone the Supabase Repository
Supabase provides an official Docker Compose setup. Clone it and set up your project directory:
git clone --depth 1 https://github.com/supabase/supabase mkdir supabase-project cp -rf supabase/docker/* supabase-project/ cp supabase/docker/.env.example supabase-project/.env cd supabase-project
The --depth 1 flag creates a shallow clone, saving time and disk space.
Step 3: Configure Environment Variables
This is the most critical step. Open the .env file and configure your secrets:
nano .env
Generate Secure Keys
You'll need to generate several secure values:
JWT Secret (at least 32 characters):
openssl rand -base64 32
Anon and Service Role Keys:
Use the Supabase JWT Generator or generate them manually with your JWT secret.
Essential Configuration
Update these values in your .env file:
# Database POSTGRES_PASSWORD=your-secure-database-password # JWT Configuration JWT_SECRET=your-32-character-minimum-secret ANON_KEY=your-generated-anon-key SERVICE_ROLE_KEY=your-generated-service-key # Site URL (your domain) SITE_URL=https://your-domain.com API_EXTERNAL_URL=https://api.your-domain.com # Dashboard credentials DASHBOARD_USERNAME=admin DASHBOARD_PASSWORD=your-secure-dashboard-password # Studio SUPABASE_PUBLIC_URL=https://your-domain.com
Security Warning: Never commit your .env file to version control. Use a secrets manager for production deployments.
Step 4: Optimize for Your Needs
One advantage of self-hosting is running only what you need. If you don't use certain features, disable them in docker-compose.yml:
Disable Unused Services
Edit docker-compose.yml and comment out or remove services you don't need:
- Logflare - Analytics (requires separate setup)
- imgproxy - Image transformation
- Edge Functions - Deno runtime for serverless functions
- Realtime - If you don't need live subscriptions
This reduces memory usage and attack surface. A minimal setup with just PostgreSQL, Auth, PostgREST, and Storage can run on 4GB RAM.
Step 5: Start Supabase
Pull the Docker images and start all services:
docker compose pull docker compose up -d
Check that everything is running:
docker compose ps
You should see all services in a "running" state. If any service is restarting, check the logs:
docker compose logs [service-name]
At this point, Supabase Studio should be accessible at http://your-server-ip:3000.
Step 6: Set Up Nginx and SSL
For production, you need a reverse proxy with SSL. Here's how to set up Nginx with Let's Encrypt:
Install Nginx
sudo apt install nginx -y
Create Nginx Configuration
Create a new configuration file:
sudo nano /etc/nginx/sites-available/supabase
Add this configuration:
server {
listen 80;
server_name your-domain.com api.your-domain.com;
location / {
proxy_pass http://localhost:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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_cache_bypass $http_upgrade;
}
}
Enable the site:
sudo ln -s /etc/nginx/sites-available/supabase /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx
Install SSL with Certbot
sudo apt install certbot python3-certbot-nginx -y sudo certbot --nginx -d your-domain.com -d api.your-domain.com
Certbot will automatically configure SSL and set up auto-renewal.
Step 7: Verify Your Deployment
Test your deployment:
- Access Studio: Navigate to
https://your-domain.com:3000(or configure Nginx to proxy Studio) - Test the API:
curl https://api.your-domain.com/rest/v1/ \ -H "apikey: YOUR_ANON_KEY"
- Check Auth: Try creating a test user through the Studio interface
Post-Deployment: What's Next?
Congratulations—you have a running Supabase instance. But deployment is just the beginning.
Set Up Backups
Self-hosted means you're responsible for backups. Supabase Cloud handles this automatically; you don't have that luxury. At minimum, set up:
- Database backups: pg_dump scheduled via cron
- Storage backups: Sync to S3-compatible storage
- Configuration backups: Version control your docker-compose.yml and .env template
For detailed backup strategies, read our complete backup and restore guide.
Configure OAuth Providers
Unlike Supabase Cloud, self-hosted Auth configuration happens in the docker-compose.yml file, not the dashboard. You'll need to set environment variables for each OAuth provider. Check our auth providers documentation for the specific variables needed.
Monitor Your Instance
Set up monitoring for:
- Container health and resource usage
- PostgreSQL performance metrics
- Disk space (databases grow over time)
- SSL certificate expiration
Tools like Prometheus, Grafana, or even simple solutions like Uptime Kuma can help.
The Easier Path: Using Supascale
The steps above work, but they require ongoing maintenance: updating containers, managing secrets, configuring backups, and troubleshooting issues. This is where Supascale changes the equation.
Instead of managing Docker Compose files manually, Supascale provides:
- One-click deployment of Supabase projects
- Automated S3 backups with one-click restore
- Custom domains with free SSL certificates
- OAuth configuration through a simple UI
- Selective services: Run only what you need
- Full REST API for automation
At $39.99 one-time (unlimited projects), you get the cost benefits of self-hosting without the operational burden. Check our installation guide to get started.
Common Issues and Troubleshooting
Services Keep Restarting
Usually a memory issue. Check with docker stats and consider:
- Adding more RAM
- Disabling unused services
- Adjusting PostgreSQL's
shared_buffers
Can't Access Studio
Ensure SUPABASE_PUBLIC_URL in .env matches your actual URL. The Studio needs to know its public address for API calls.
Authentication Not Working
Verify your JWT_SECRET is consistent across all services and that ANON_KEY/SERVICE_ROLE_KEY were generated with the same secret.
Database Connection Issues
Check that POSTGRES_PASSWORD matches in both the database service and connecting services.
Conclusion
Deploying Supabase on your own server is achievable with Docker and some configuration work. The process involves preparing your server, configuring secrets carefully, starting the containers, and setting up SSL for production use.
The trade-off is clear: you gain control and cost savings but take on operational responsibility. For teams comfortable with Docker and Linux administration, this is manageable. For those who want the benefits of self-hosting without the maintenance burden, tools like Supascale bridge that gap.
Ready to deploy? Start with the system requirements, then follow this guide step by step. And when you need reliable backups without the complexity, Supascale is here to help.
