How to Deploy Supabase on Your Own Server: Step-by-Step Guide

Complete guide to self-hosting Supabase with Docker. Learn prerequisites, configuration, SSL setup, and production tips for your VPS deployment.

Cover Image for How to Deploy Supabase on Your Own Server: Step-by-Step Guide

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:

SpecificationMinimumRecommended
RAM4GB8GB+
CPU2 cores4+ cores
Storage50GB SSD80GB+ NVMe SSD
OSUbuntu 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:

ProviderSpecsMonthly Cost
Hetzner8 vCPU, 32GB RAM~$50
DigitalOcean8 vCPU, 16GB RAM~$96
Vultr6 vCPU, 16GB RAM~$80
Supabase CloudSimilar 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:

  1. Access Studio: Navigate to https://your-domain.com:3000 (or configure Nginx to proxy Studio)
  2. Test the API:
curl https://api.your-domain.com/rest/v1/ \
  -H "apikey: YOUR_ANON_KEY"
  1. 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.


Further Reading