21+ years in hosting · Jaipur, India · INR billing with 18% GST · 24/7 email support
Blog · WebJi® India

Self-Host Supabase on a VPS

Quick answer

Self-hosting Supabase means running its official Docker Compose stack — Postgres, auth, REST, Realtime, storage and Studio — on your own VPS. Supabase recommends 8 GB RAM and 4 CPU cores, with 4 GB and 2 cores as the minimum. Clone a pinned release, generate secrets, start the stack and put Nginx with HTTPS in front.

For developers who want Supabase's Postgres, auth and APIs on a server they control, set up securely with HTTPS, backups and safe upgrades.

✓ In business since 2005
✓ INR + GST billing
✓ 24/7 Email Support — avg reply < 60 min
GuideWebJi®
knowledge
Read time
5 min
Sections
9
Updated
14 Nov 2026
Written by
WebJi® team

What does a self-hosted Supabase stack run?

Self-hosted Supabase is a Docker Compose stack of about ten services — Postgres plus the APIs, auth, realtime, storage and dashboard around it — all reached through one API gateway on port 8000. Knowing which container does what is half of debugging a failed install.

Core services in the official Supabase Docker setup
ServiceJob
PostgresThe database, with Supabase roles, schemas and extensions preloaded
API gateway (Envoy by default, Kong optional)Routes every public request to the right service
AuthSign-ups, logins, OAuth and session tokens
PostgRESTTurns tables into a REST API at /rest/v1/
RealtimeBroadcasts database changes to subscribed clients over WebSockets
Storage and imgproxyFile buckets with Postgres-based permissions, plus image resizing
Edge RuntimeDeno-based functions at /functions/v1/
Studio and postgres-metaThe dashboard and the API it uses to manage the database
SupavisorPostgres connection pooler

Logs and analytics (Logflare and Vector) are not in the default setup; they are an optional add-on that raises memory use. If Docker itself is new to you, Docker hosting explained covers the basics.

How big a VPS does self-hosted Supabase need?

Supabase's own documentation sets a minimum of 4 GB RAM, 2 CPU cores and 40 GB SSD, and recommends 8 GB RAM, 4 cores and 80 GB SSD or more. Treat the minimum as a development box and the recommendation as the starting point for a production app.

Supabase self-hosting requirements, from the official Docker guide
ResourceMinimumRecommended
RAM4 GB8 GB+
CPU2 cores4 cores+
Disk40 GB SSD80 GB+ SSD

Postgres is the component that decides when to grow, because its cache and concurrent queries scale with your data. You can lower the footprint by deleting services you do not use, such as Realtime, Storage, imgproxy or Edge Functions, from docker-compose.yml. Choose NVMe storage: Postgres and the storage volume are both disk-heavy.

How do you install Supabase on a VPS?

Clone a pinned self-hosted/v* release of the Supabase repository, copy its docker/ folder into a project directory, create .env from the example, generate secrets, then start the stack. On Debian, Ubuntu or RHEL-family servers, Supabase also offers a setup script that does all of this, but reading each step once is worth it.

# Pin a release tag; check github.com/supabase/supabase/tags for the latest
git clone --depth 1 --branch self-hosted/v0.8.4 https://github.com/supabase/supabase
mkdir supabase-project
cp -rf supabase/docker/. supabase-project
cd supabase-project && cp .env.example .env
printf 'ref=self-hosted/v0.8.4\n' > .supabase-version
docker compose pull

# Generate secrets and the new API keys, then review .env
sh utils/generate-keys.sh
sh utils/add-new-auth-keys.sh

# Start and wait for health checks
sh run.sh start
docker compose ps

After a minute, every service should show Up (healthy). If one is stuck at created, run sh tests/test-container-logs.sh and then sh run.sh logs <service> for the failing one. An entrypoint error from the gateway usually means the files were checked out with Windows CRLF line endings.

Which Supabase secrets must you set before the first start?

Never start Supabase with the placeholder values from .env.example: generate the database password, API keys and encryption keys, set your public URLs, and change the dashboard password first. The Postgres password in particular is written into the database on first boot.

  • POSTGRES_PASSWORD: set before the first start; letters and numbers only avoids URL-encoding problems in connection strings. Change it later only with sh utils/db-passwd.sh.
  • SUPABASE_PUBLISHABLE_KEY and SUPABASE_SECRET_KEY: the publishable key goes in browser and mobile apps; the secret key stays on servers only.
  • DASHBOARD_USERNAME and DASHBOARD_PASSWORD: Studio sits behind HTTP basic auth. The password must contain at least one letter.
  • SUPABASE_PUBLIC_URL, API_EXTERNAL_URL, SITE_URL: your real HTTPS domains, or email links and OAuth redirects point at the wrong host.
  • SMTP_ settings: a production mail server, or sign-up and password-reset emails will not arrive.

Run sh run.sh secrets to print the key credentials at any time. Keep .env out of Git, and consider a secrets manager for production.

How do you put Supabase behind Nginx with HTTPS?

Terminate TLS on Nginx at port 443, proxy everything to the gateway on 127.0.0.1:8000, pass the WebSocket upgrade headers for Realtime, and keep port 8000 closed to the internet. Without the upgrade headers, Realtime connects and then drops.

server {
    listen 443 ssl;
    server_name api.example.com;
    # ssl_certificate lines are added by certbot --nginx

    location / {
        proxy_pass http://127.0.0.1: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-Forwarded-Proto $scheme;
        proxy_read_timeout 3600s;
    }
}

Issue the certificate with sudo certbot --nginx -d api.example.com, then sudo nginx -t and reload; Certbot SSL on Nginx walks through it. One trap: Docker writes its own iptables rules, so a port published in Compose stays reachable even if ufw denies it. Change the gateway and pooler port mappings in docker-compose.yml to bind to 127.0.0.1 (for example 127.0.0.1:8000:8000), and expose Postgres (5432 and 6543 by default) only if a remote app truly needs it.

How do you check that the Supabase APIs work?

Call the bundled hello Edge Function with your publishable key, then connect an app with supabase-js and confirm a Realtime change arrives live. Each test proves a different layer: gateway, keys and WebSockets.

  1. Gateway and keys: curl https://api.example.com/functions/v1/hello --header 'apikey: YOUR_PUBLISHABLE_KEY' should return the function's response, not a 401 or 502.
  2. Install the client: npm install @supabase/supabase-js, then create it with SUPABASE_PUBLIC_URL and the publishable key.
  3. In Studio, create a table, enable Row Level Security and add a read policy before inserting rows from the app.
  4. Open two browser tabs, subscribe to the table in one and insert a row in the other. A row appearing live proves Realtime and the proxy headers.

How do you back up and upgrade self-hosted Supabase?

Back up two things on a schedule — a Postgres dump and the volumes/storage folder — copy both off the server, and upgrade only with the bundled update.sh after a fresh backup. A database dump alone loses every uploaded file.

#!/bin/sh
# /opt/supabase-backup.sh — run from cron
cd /opt/supabase-project
D=$(date +%F)
docker compose exec -T db pg_dump -U postgres -Fc postgres > /opt/backups/db_$D.dump
tar -czf /opt/backups/storage_$D.tar.gz volumes/storage

Schedule it with 0 3 * * * /opt/supabase-backup.sh >> /var/log/supabase-backup.log 2>&1 (see crontab examples) and ship the files to another machine or object storage, following the 3-2-1 backup rule. Test a restore on a scratch instance before you need it.

Supabase publishes tested self-hosted snapshots about once a month. Read the changelog, back up, then run update.sh, which merges the new configuration over yours. Never run sh reset.sh or docker compose down -v on a live stack: both delete the database and storage data.

When is managed Supabase the better choice?

Managed Supabase is the better buy when you need several projects, branching or point-in-time recovery, or when nobody on the team wants to run a server; self-host when data must stay on infrastructure you control or steady usage makes a fixed server cheaper. One self-hosted stack is one project, so a second product means a second stack and a second backup job.

A WebJi® VPS gives root access from the first boot, with plans from ₹499 a month before 18% GST; pick a size with at least 8 GB RAM for production, and ask support@webji.services for larger configurations. Support answers 24/7 in Hindi and English, with an average first reply under 60 minutes. If you also plan to run a model or n8n on the same machine, read running an LLM on a VPS or installing n8n on a VPS first, because they compete for the same RAM.

FAQ

Frequently asked questions

Can self-hosted Supabase run on a 4 GB VPS?

Yes, 4 GB RAM and 2 cores is Supabase's stated minimum, suitable for development and small workloads. Remove services you do not use, such as Edge Functions or imgproxy, to free memory. For production, the recommended 8 GB and 4 cores leaves room for Postgres to cache data.

Why does Supabase Realtime disconnect behind Nginx?

The proxy is not passing the WebSocket upgrade. Set proxy_http_version 1.1, the Upgrade and Connection headers, and a long proxy_read_timeout, then reload Nginx and retest with two browser tabs.

Is the old JWT_SECRET, anon and service_role key setup still used?

Current self-hosted releases add publishable and secret API keys with an asymmetric signing key pair, created by utils/add-new-auth-keys.sh. Older guides that only mention the anon and service_role keys describe the legacy setup; follow the docs for the release tag you installed.

Can I host several projects on one self-hosted Supabase?

Not the way the hosted platform does. A self-hosted stack has one Studio and one database, so separate products need separate stacks, each with its own ports, domain and backups, or separate schemas with careful row-level policies.

Steps checked against Supabase's self-hosting Docker guide on 14 November 2026 · Reviewed by the WebJi® team, Jaipur.

WebJi® since 2005

Ready to get started with WebJi®?

Join 12,000+ businesses across India and overseas. INR pricing, 18% GST shown before payment and 24/7 email support in Hindi and English — average first reply under 60 minutes.