Self-hosted Supabase gives you the same building blocks as the hosted platform, a PostgreSQL database with an instant REST API, authentication, file storage, realtime subscriptions and edge functions, running in Docker on a server you control. The official requirements are modest: 4 GB of RAM and 2 CPU cores to start, 8 GB and 4 cores recommended.
This post covers what self-hosted Supabase needs, the install, the secrets you must change before first start, which ports end up public and how to close the ones that should not be, mail for sign-ups, a sizing table with real prices, and backups. Details come from the Supabase self-hosting guide and the Docker setup release self-hosted/v0.8.4 of 5 November 2026, which includes security fixes for Storage, so update existing installs first.
What does self-hosted Supabase need?
The Docker self-hosting guide publishes a short table for running every component, sized for development and small to medium production workloads:
| Resource | Minimum | Recommended |
|---|---|---|
| RAM | 4 GB | 8 GB or more |
| CPU | 2 cores | 4 cores or more |
| Disk | 40 GB SSD | 80 GB or more SSD |
That covers a stack of about a dozen containers behind one API gateway:
- Postgres 17, the default since the 0.6.0 release, with Supavisor pooling connections in front of it.
- Envoy as the API gateway, now the default (Kong is an optional override and marked for removal).
- Auth (sign-ups, logins, sessions), PostgREST (the REST API), Realtime (change broadcasts), Storage with imgproxy (files and image transforms), Edge Runtime (functions on Deno), postgres-meta and Studio, the dashboard.
Two ways to trim it. If you do not use Realtime, Storage, imgproxy or Edge Functions, the guide says you can delete those services from docker-compose.yml. And Logs and Analytics (Logflare plus Vector) are off by default because they add memory; turn them on only if you will read them. Since v0.8.4 the functions container also has a default memory limit of 2 GiB, adjustable with FUNCTIONS_MEMORY_LIMIT.
How do you install self-hosted Supabase?
On a fresh Debian or Ubuntu VPS, the quick-start script installs Docker if needed, fetches the configuration, generates every secret and the JWT signing keys, and asks for your URLs:
curl -fsSL https://supabase.link/setup.sh | sh
cd supabase-project
sh run.sh start
docker compose ps
After a minute every service should show Up (healthy). The manual path clones a pinned tag such as self-hosted/v0.8.4 and runs utils/generate-keys.sh and utils/add-new-auth-keys.sh yourself. Either way, three things before real data goes in:
- Never start on the example secrets. The guide is blunt about it. The script handles this; on the manual path, check
.envafter running both key scripts.sh run.sh secretsprints the values your app needs: the publishable key for the frontend, the secret key for servers only, and the database password. - Set a real Studio password. Studio sits behind HTTP basic auth using
DASHBOARD_USERNAMEandDASHBOARD_PASSWORD. It is the admin panel for your whole database. - Set the URLs.
SUPABASE_PUBLIC_URL,API_EXTERNAL_URLandSITE_URLdecide where clients connect and where Auth redirects after login. Use your final HTTPS domain, not the server IP.
Which ports does Supabase open, and which should be public?
The default docker-compose.yml publishes three ports on every interface:
| Port | Service | Should be open to |
|---|---|---|
| 8000/tcp | API gateway: REST, Auth, Storage, Realtime, Functions and Studio | Only your reverse proxy, once HTTPS is set up |
| 5432/tcp | Supavisor, session mode | Your app servers and admin IPs only |
| 6543/tcp | Supavisor, transaction mode | Your app servers and admin IPs only |
| 80/tcp, 443/tcp | Your reverse proxy (Caddy or nginx), added by you | Everyone |
| 22/tcp | SSH | Your IP, keys only |
Postgres itself is not exposed; direct connections for migrations and pg_dump need a compose change. The trap is the pooler. Docker writes its own iptables rules for published ports, and they take effect before UFW, so ufw deny 5432 does not close it. Either change the mappings in docker-compose.yml to bind to localhost (for example 127.0.0.1:5432:5432) and reach the database over an SSH tunnel or a private network, or filter in the DOCKER-USER chain.
For HTTPS, the guide recommends a reverse proxy in front of the gateway: Caddy or nginx on 443, forwarding to 8000 on localhost. The guide says production setups need it, especially with OAuth sign-in providers. Every Noded VPS includes 100 Gbps of always-on Layer 3/4 DDoS protection; request limits on the public API are yours to set in the proxy.
Mail for sign-ups and password resets
Auth sends confirmation links, magic links and password resets, so it needs a working SMTP server. The guide's variables, with placeholders:
SMTP_ADMIN_EMAIL=ADMIN-ADDRESS
SMTP_HOST=smtp.relay-provider.example
SMTP_PORT=465
SMTP_USER=RELAY-USERNAME
SMTP_PASS=RELAY-PASSWORD
SMTP_SENDER_NAME=Your App
Use a relay or transactional provider on its authenticated submission port, 465 as above or 587, and publish its SPF and DKIM records on your domain. Restart the stack after changing them. Our email hosting page explains why we recommend a relay for outbound mail. If your team already runs an identity provider, Supabase self-hosting also documents SAML SSO; our Authentik vs Keycloak guide covers running one.
Which Noded plan fits self-hosted Supabase?
The first two rows match the documented minimum and recommended specs; the workload notes are our estimate. Prices are monthly, in euros, excluding VAT, from our live catalogue.
| Use | Plan | vCPU / RAM / SSD | Bucharest | Amsterdam |
|---|---|---|---|---|
| Documented minimum: development, staging, a small app | VPS II | 2 / 4 GB / 40 GB | €6 | €8 |
| Recommended RAM, light production (estimate) | VPS III | 2 / 8 GB / 60 GB | €10 | €14 |
| Documented recommendation: 4 cores, 8 GB+, 80 GB | VPS IV | 4 / 16 GB / 80 GB | €16 | €24 |
| Busy production with Logs and Edge Functions (estimate) | VPS V | 6 / 24 GB / 100 GB | €30 | €42 |
| Large database before moving Postgres to its own server | VPS VI | 8 / 32 GB / 120 GB | €58 | €74 |
Extra disk is €4 a month per 50 GB, up to 150 GB; Storage keeps uploaded files on local disk by default and can be pointed at S3-compatible storage when they outgrow it. Bucharest deploys straight away; Amsterdam, Frankfurt and Vienna take preorders with about 14 days' delivery, and checkout shows current stock. Postgres memory is usually what you outgrow first, and our PostgreSQL sizing post explains how to read the working set before resizing.
Backups and updates
Self-hosted means the platform's point-in-time recovery is not included. What to save, in order:
- The database. A nightly
pg_dumpover a direct connection is the simplest restorable copy. Users, auth data and your Storage permissions all live in Postgres. .env. It holds the JWT signing keys and API keys. Lose it and every issued token and client configuration breaks.- Storage files. On the default file backend they sit in
volumes/storage. - Function code in
volumes/functions, if it is not already in Git.
Keep the copies off the server, for example on a second VPS in another location, as our restic and Borg backup target post describes. Never run sh reset.sh on a live system: it deletes the database and storage directories by design.
Supabase publishes a tested Docker snapshot about once a month. update.sh merges the new configuration into yours; read the changelog first, since releases like v0.8.4 can change behaviour (it stopped the gateway adding CORS headers to Edge Functions responses).
Questions people ask
How much RAM does self-hosted Supabase need?
The guide's minimum is 4 GB with 2 cores and 40 GB of SSD, and it recommends 8 GB or more with 4 cores and 80 GB. Removing services you do not use, such as Realtime or Edge Functions, lowers that.
Is self-hosted Supabase free?
The software is open source and free to run. You pay for the server, the mail relay and any object storage, and you take on updates, backups and security yourself.
Why is my Supabase Postgres port reachable after I blocked it with UFW?
Docker's rules for published ports bypass UFW. Bind 5432 and 6543 to localhost in docker-compose.yml, or filter in the DOCKER-USER chain.
Can I move a project from Supabase Cloud to my own server?
Yes. The self-hosting docs include a guide to restoring a platform project into a self-hosted instance, covering the database and copying Storage objects.
Keeping your Supabase data in the EU
Everything your users hand your app, their accounts, rows and files, ends up in this one Postgres database and its storage volume, so the server's location is where that personal data lives. Pick Bucharest or Amsterdam and the VPS stays in the EU under GDPR, operated by an EU company on our own network, AS60982, with our data processing agreement part of the Terms. The GDPR hosting page has the details. Start on VPS II for staging or VPS IV for production from the VPS hosting page, change every secret before first start, and close the pooler ports before you point an app at it.