Back to Resources
Self-Hosting

How to Deploy Self-Hosted Supabase with Docker: Complete Tutorial

BI
Bilal Nazam
March 21, 202510 min read

Why Docker Compose for Supabase?

Supabase consists of 8+ services: PostgreSQL, PostgREST, GoTrue (auth), Realtime, Storage, Kong (API gateway), Supabase Studio, and more. Docker Compose orchestrates all of these with a single command, making self-hosted Supabase manageable even for teams without deep DevOps expertise.

Server Requirements

  • Ubuntu 22.04 LTS
  • Minimum: 2 vCPU, 4GB RAM, 40GB SSD
  • Recommended: 4 vCPU, 8GB RAM, 100GB SSD
  • A domain name and DNS access

Step 1: Install Docker Engine

sudo apt update && sudo apt upgrade -y
sudo apt install -y ca-certificates curl gnupg

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg]   https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" |   sudo tee /etc/apt/sources.list.d/docker.list

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo usermod -aG docker $USER

Step 2: Clone Supabase and Configure

git clone --depth 1 https://github.com/supabase/supabase
cd supabase/docker
cp .env.example .env

Generate the required secrets:

# Generate JWT secret (minimum 32 chars)
openssl rand -base64 32

# Generate API keys (use Supabase's JWT tool or this approach)
# Visit https://supabase.com/docs/guides/self-hosting#api-keys for instructions

Edit .env with your values:

############
# Secrets - Generate fresh values for production!
############
POSTGRES_PASSWORD=your-strong-password-here
JWT_SECRET=your-jwt-secret-minimum-32-chars
ANON_KEY=eyJhbGci...  # Generated from JWT_SECRET
SERVICE_ROLE_KEY=eyJhbGci...  # Generated from JWT_SECRET

############
# API - Your public domain
############
SITE_URL=https://yourdomain.com
API_EXTERNAL_URL=https://api.yourdomain.com

############
# Studio - Internal access
############
STUDIO_DEFAULT_ORGANIZATION=Your Org
STUDIO_DEFAULT_PROJECT=Production

############
# Email - Configure SMTP
############
SMTP_ADMIN_EMAIL=admin@yourdomain.com
SMTP_HOST=smtp.youremailprovider.com
SMTP_PORT=587
SMTP_USER=your-smtp-user
SMTP_PASS=your-smtp-password
SMTP_SENDER_NAME=Your App Name

Step 3: Configure Nginx Reverse Proxy

sudo apt install nginx certbot python3-certbot-nginx -y

Create /etc/nginx/sites-available/supabase:

server {
    server_name api.yourdomain.com;

    location / {
        proxy_pass http://localhost:8000;
        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;
    }

    # WebSocket support for Realtime
    location /realtime/ {
        proxy_pass http://localhost:8000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}
sudo ln -s /etc/nginx/sites-available/supabase /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d api.yourdomain.com

Step 4: Start Supabase

cd ~/supabase/docker
docker compose up -d

Verify all containers are running:

docker compose ps

Step 5: Set Up Automated Backups

sudo mkdir -p /backups/supabase
sudo crontab -e

Add this cron job:

# Daily backup at 2 AM
0 2 * * * docker exec supabase-db pg_dumpall -U postgres | gzip > /backups/supabase/backup-$(date +%Y%m%d).sql.gz

# Keep only last 7 days
0 3 * * * find /backups/supabase -name "*.sql.gz" -mtime +7 -delete

Step 6: Configure Firewall

sudo ufw allow 22/tcp    # SSH
sudo ufw allow 80/tcp    # HTTP
sudo ufw allow 443/tcp   # HTTPS
sudo ufw deny 5432/tcp   # Block direct Postgres access
sudo ufw deny 8000/tcp   # Block direct Kong access
sudo ufw enable

Updating Supabase

cd ~/supabase
git pull
cd docker
docker compose pull
docker compose up -d

Need this set up professionally? Our self-hosted deployment service gets you running in 24 hours with full documentation.

Categorized In

supabasedockerself-hostedtutorialdevops

Frequently Asked Questions

How do I access Supabase Studio on self-hosted?

Supabase Studio runs on port 3000 by default. Set up a separate Nginx vhost for studio.yourdomain.com proxying to localhost:3000, and protect it with basic auth or restrict to your IP.

Can I run self-hosted Supabase without a domain name?

Yes, using an IP address, but SSL becomes more complex. For production, always use a domain with Let's Encrypt SSL.

How do I monitor self-hosted Supabase?

Use docker compose logs -f for live logs, set up UptimeRobot for uptime monitoring, and consider Grafana + Prometheus for detailed metrics on larger deployments.

Share This Intelligence

Start Your Migration Strategy

Don't let vendor lock-in stifle your growth. Get a professional roadmap to Supabase excellence today.

Free Architectural Audit