itsez.dev
๐Ÿ“–Tutorial

How to install Supabase on a VPS

2026-07-30ยท5 min readยทData & backend

Supabase packages PostgreSQL with authentication, APIs, storage and a dashboard for application backends. Its self-hosted deployment is a multi-service Docker stack, so this guide focuses on using the official Compose files, protecting secrets and exposing only the public gateway.

Prerequisites

Choose Ubuntu 22.04 or 24.04 with SSH, a public IP and a dedicated domain such as api.example.com. Official minimums are 4 GB RAM minimum (8 GB recommended), 2+ CPU cores, 40+ GB SSD. A development installation can use a modest machine, while production needs room for PostgreSQL, logs, storage and migrations.

You need Docker Compose, a secure way to generate secrets and storage outside the VPS for backups. Supabase self-hosting assumes that you can maintain the operating system and database. It is not a managed database service.

Step 1, Connecting to your server

Connect and create a protected working directory:

ssh root@SERVER_IP
apt update && apt upgrade -y
apt install -y ca-certificates curl git
mkdir -p /opt/supabase
cd /opt/supabase
chmod 750 /opt/supabase

Open only SSH, HTTP and HTTPS at the provider level. Avoid installing another reverse proxy or PostgreSQL instance until you understand the ports used by the official stack.

Step 2, Installing Docker and Docker Compose

Install Docker Engine and the Compose plugin using Docker's official Ubuntu instructions. Verify them:

docker --version
docker compose version
systemctl enable --now docker

Check available disk and memory before pulling images:

df -h
free -h

Step 3, Running the official Supabase stack

Supabase maintains the self-hosted Docker configuration in its official repository. The recommended way to start is the official setup script:

curl -fsSL https://supabase.link/setup.sh | sh

Alternatively, clone the repository manually:

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

Secrets and JWT keys

Supabase now uses asymmetric JWT key pairs instead of a single JWT_SECRET. After cloning, generate the required keys with the included helper scripts:

./docker/utils/generate-keys.sh
./docker/utils/add-new-auth-keys.sh

These scripts create the RSA keypair for JWT signing and add the new keys to the auth configuration. The files docker/volumes/api/kong.yml manages the Gateway and docker/volumes/db/init/ handles the database.

Critical environment variables

Open .env and replace every placeholder value. The default .env.example values are DANGEROUS and must never be used in production.

Variable Requirements
DASHBOARD_PASSWORD Must contain at least one letter (numbers-only passwords are rejected)
POSTGRES_PASSWORD Use letters and numbers only to avoid URL-encoding issues

All other placeholder values in .env must also be replaced with unique generated values. Never publish the file.

Windows users: If you clone the repository on Windows, ensure line endings are LF (Unix style). CRLF line endings break the Kong Gateway entrypoint. Use git config --global core.autocrlf false before cloning, or convert with dos2unix.

Validate the complete official project before starting it:

docker compose config
docker compose pull
docker compose up -d
docker compose ps

The official Compose file is the example deployment for this guide. Do not replace it with a short custom file, because removing a gateway, migration or storage service can produce a partially working backend.

Step 4, Configuring the reverse proxy

Supabase ships official Caddy and Nginx override files. Enable them with:

sh run.sh config add caddy
# or
sh run.sh config add nginx

Route api.example.com to the gateway's localhost port from the official Compose file. Update these variables in .env to match your domain:

SUPABASE_PUBLIC_URL=https://api.example.com
API_EXTERNAL_URL=https://api.example.com
SITE_URL=https://api.example.com

Terminate TLS at the proxy, forward the original host and protocol headers and keep PostgreSQL and internal services private. If Studio is needed remotely, protect it with the access method documented for your version instead of opening every container port.

WebSocket: Supabase Realtime requires WebSocket support in your proxy. Ensure your reverse proxy configuration allows WebSocket upgrades (Caddy does by default; Nginx needs explicit proxy_set_header Upgrade $http_upgrade and proxy_set_header Connection "upgrade").

Test the HTTPS endpoint, an authenticated API request and a storage operation. A valid dashboard page alone does not prove that database migrations, authentication or object storage are healthy.

Step 5, First access and initial setup

Open the Studio address through the protected route and sign in with the credentials configured in .env. Create a test project or use the default project only for evaluation. Record the project URL and public anonymous key in your application configuration, but keep service-role keys on the server.

Create a table, apply a migration and test authentication from a disposable application. Confirm that row-level security is enabled where it should be. Never use a service-role key in browser code.

Maintenance

Back up PostgreSQL, storage objects and all environment secrets. Review the upstream release notes before updating the repository and images. Take a database snapshot before migrations, run the update in a maintenance window and verify auth, APIs and storage afterward.

Monitor database connections, disk, object storage, gateway errors and container health. If a service fails, collect docker compose ps, the service logs and the effective Compose configuration before restarting or deleting anything.

Tools mentioned

Supabase

โ†—

Postgres backend with database, auth, storage, realtime and edge functions.

FreemiumNo cardOSS

2 projects, 500 MB database, 1 GB storage, 5 GB egress and 50,000 monthly active users.

ABOUT US

Honest, independent, no fluff.

No paid placements. Just a clear look at what this does, what it costs, and what to know before you commit.

Read moreโ†’

FAQ

Questions, answered.

Can Supabase run on a small VPS?๏ผ‹

It needs more resources than a plain PostgreSQL container because several services run together. Check the current official requirements before choosing a server.

Which Supabase ports should be public?๏ผ‹

Expose only the gateway through HTTPS. Keep PostgreSQL, Studio and internal services on private interfaces unless the official deployment requires otherwise.

What is the most important Supabase backup?๏ผ‹

Back up PostgreSQL data, storage objects and the deployment secrets, then test a complete restore.