How To Self-Host Supabase for $3

By Andrew Melbourne1/5/2025

Blog Home

tldr: Get a Hetzner VPS and run docker compose up db rest auth kong --no-deps -d

Why Self-Host

The pro tier for hosted Supabase costs $25 PER PROJECT. Free tier projects get suspended after 7 days of inactivity. Often my projects aren't receiving weekly traffic, so I've opted to self-host!

The $3 Server

At the time of writing of this article, Hetzner offers a VPS with 4GB RAM for €3.29/mo. You should only need about 2GB RAM, so this will be more than enough. If you want something US based, there are 2GB options that are slightly more expensive (this is what I use). Details about connecting to a VPS can be found here

Running Barebones Supabase

The self-hosted Supabase distribution comes with 13 services. It is likely that your project only needs a handful of these. Running only the necessary services will significantly reduce memory usage.

First, follow these instructions to install docker.

Next, run these (from the official Self-Hosting with Docker guide by Supabase):

# Get the code
git clone --depth 1 https://github.com/supabase/supabase

# Go to the docker folder
cd supabase/docker

# Copy the fake env vars (change these eventually)
cp .env.example .env

# Pull the latest images
docker compose pull

⚠️ BE SURE YOU HAVE SWAPPED THE DEFAULT VALUES IN .env FOR SECURE ONES. You can generate secure API keys on Supabase's website here.

Here's the Trick

This command lets you operate a minimal Supabase instance with only the essentials:

docker compose up db rest auth kong --no-deps -d

A bit about each one:

For a full list of services, check out the docker-compose.yml. Also worth checking out is the Architecture Page from the Supabase docs. Use this to determine which services you need.

You can also optionally add studio to the list of services if you want access to the management interface.

Here's a snapshot taken with htop of system resource usage with all 13 services running (I use a US based Hetzner VPS with 2GB RAM for closer to $5/mo):

And here's how we're looking only running db,rest, auth, and kong Much better!

Apply Migrations From Your Local

To apply migrations, you will need supavisor running (add that when running the docker compose command). The tenant id and postgres password can be found in .env. We'll also create a tunnel with ssh so you can connect directly to postgres.

ssh -L 5432:localhost:5432 root@5.161.82.203

npx supabase db push --db-url "postgres://postgres.your-tenant-id:<postgres password>@localhost:5432/postgres"

Refer to the CLI Docs for a comprehensive list of available commands.

Access Studio and createClient()

Access the studio by navigating to <your vps ip>:8000 in the browser. Log in with the DASHBOARD_USERNAME and DASHBOARD_PASSWORD from your .env

Create client connections with:

import { createClient } from '@supabase/supabase-js'

const supabase = createClient('http://<your vps ip>:8000', 'public-anon-key')

Final Touches

The client creation snippet above uses an HTTP connection. For production apps, I recommend creating a reverse proxy with NGINX and using something like Certbot to generate SSL certificates for secure connections over HTTPS.

⚠️ BE SURE YOU HAVE SWAPPED THE DEFAULT VALUES IN .env FOR SECURE ONES. You can generate secure API keys on Supabase's website here.

Congratulations! You're now ready to scale to ~dozens~ of users!