# How to self-host Supabase with Docker Compose

> Supabase Docker Compose setup with the official self-hosting files: hardware needs, generated keys, Studio login, HTTPS via the Caddy overlay, backups, updates.

## Key facts

| Fact | Value |
|---|---|
| App | Supabase (https://appsgit.com/apps/supabase) |
| Difficulty | intermediate |
| Time | about 30 minutes |
| Requirements | 2 vCPU / 4 GB RAM minimum (4 vCPU / 8 GB+ recommended); 40 GB+ SSD storage; Docker + Docker Compose v2, git and openssl; A domain name pointing at the server |
| Last updated | 2026-10-06 |

## What is Supabase?

Supabase is an open source backend platform built on PostgreSQL. One stack gives you a Postgres database, auto-generated REST and GraphQL APIs, authentication, file storage, realtime subscriptions, edge functions and a web dashboard called Studio. It is the best-known open source alternative to Firebase and is licensed under Apache-2.0.

Be clear about the size before you start: self-hosted Supabase is not one container. The official stack runs around ten services (Studio, an Envoy API gateway, Auth, PostgREST, Realtime, Storage, imgproxy, postgres-meta, Edge Runtime, Supavisor and Postgres itself), and you are responsible for securing, backing up and upgrading all of it.

## Requirements

- From the official docs: at least 4 GB of RAM, 2 CPU cores and a 40 GB SSD. The recommendation is 8 GB or more, 4 cores and 80 GB or more.
- Docker Engine, Docker Compose v2, `git` and `openssl`.
- A domain with an A record for the server, for HTTPS.

## Step 1: Prepare the server

This guide assumes Ubuntu 24.04 with Docker installed from the [official Docker Engine guide](https://docs.docker.com/engine/install/ubuntu/). Supabase versions its self-hosting files with `self-hosted/vX.Y.Z` tags; pin one rather than tracking `master`:

```bash
git clone --depth 1 --branch self-hosted/v0.8.2 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.2\n' > .supabase-version
```

Supabase also offers a one-line installer (`setup.sh`) that does the same thing, but the manual route shows you exactly what lands on the server.

## Step 2: Create the Docker Compose file

You do not write this Compose file by hand. The cloned `docker-compose.yml` is the official stack, with every image pinned to a tested version, and `.env` drives all of it. The important part is replacing every default secret before the first start. The example file warns that all of them must change, and the repo ships scripts that generate them:

```bash
sh utils/generate-keys.sh --update-env
sh utils/add-new-auth-keys.sh --update-env
```

The first script writes `POSTGRES_PASSWORD`, `JWT_SECRET`, the legacy `ANON_KEY` and `SERVICE_ROLE_KEY`, `SECRET_KEY_BASE`, `VAULT_ENC_KEY`, `REALTIME_DB_ENC_KEY`, `PG_META_CRYPTO_KEY`, `DASHBOARD_PASSWORD` and the Logflare and storage keys. The second derives the newer `SUPABASE_PUBLISHABLE_KEY` and `SUPABASE_SECRET_KEY` from the JWT secret. If you would rather set a value yourself, use `openssl rand -hex 32` for 64-character secrets.

Then edit `.env` and set the public URLs:

```bash
SUPABASE_PUBLIC_URL=https://supabase.example.com
API_EXTERNAL_URL=https://supabase.example.com
SITE_URL=https://app.example.com
DASHBOARD_USERNAME=CHANGE_ME
```

`SITE_URL` is where your front end runs; Auth uses it for email links. Treat `SUPABASE_SECRET_KEY` and `SERVICE_ROLE_KEY` like database root passwords: they bypass row-level security and must never ship in client code.

## Step 3: Start and open the app

```bash
docker compose pull
docker compose up -d
docker compose ps
```

The first pull is several gigabytes. Wait until every service reports `healthy`, then open `http://YOUR_SERVER_IP:8000` and sign in with `DASHBOARD_USERNAME` and `DASHBOARD_PASSWORD`. Run `sh run.sh secrets` to see them again. In Studio, create a table, add a row-level security policy and copy the API URL and publishable key into your app.

## Step 4: Put it behind HTTPS

The repo includes an official Caddy overlay that terminates TLS for your domain, removes the gateway's public port 8000 and protects Studio with the dashboard credentials. Set these in `.env`:

```bash
COMPOSE_FILE=docker-compose.yml:docker-compose.caddy.yml
PROXY_DOMAIN=supabase.example.com
```

Then run `docker compose up -d`. Caddy fetches a Let's Encrypt certificate and routes `/auth/v1`, `/rest/v1`, `/storage/v1`, `/realtime/v1` and `/functions/v1` to the API and everything else to Studio.

Supavisor still publishes Postgres on 5432 and 6543 on all interfaces. Docker-published ports bypass `ufw`, so block them in your cloud provider's firewall, or only allow your own IPs, unless your apps connect to the database directly from outside the server.

## Backups and upgrades

Database dumps are the core of your backup:

```bash
docker compose exec -T db pg_dumpall -U supabase_admin > supabase-$(date +%F).sql
```

Also back up `.env` and `volumes/storage` (uploaded files). Without `.env` your JWT secret and encryption keys are gone, and existing tokens and encrypted values become unusable.

To update, read the self-hosted changelog, then run the bundled script, which merges new vendor files and adds missing `.env` keys without overwriting your values:

```bash
sh update.sh
```

## Troubleshooting

- **A service keeps restarting:** run `docker compose logs <service>`. Most first-start failures are placeholder secrets or a `.env` value with the wrong length.
- **"Invalid API key" from the client libraries:** the keys were regenerated after the containers started. Run `docker compose up -d --force-recreate`.
- **Auth emails link to localhost:** `SITE_URL` and `API_EXTERNAL_URL` still have their defaults.
- **Server runs out of memory:** stop optional services you do not use, or move to the recommended 8 GB.

## Next steps

Set `SMTP_HOST`, `SMTP_PORT`, `SMTP_USER`, `SMTP_PASS` and `SMTP_ADMIN_EMAIL` in `.env` so Auth can send real emails, switch storage to S3 with the S3 overlay, schedule nightly `pg_dumpall` runs with off-site copies, and enable only the auth providers your app needs.

## FAQ

### What port does self-hosted Supabase use?

The API gateway listens on port 8000, which serves both Supabase Studio and the REST, Auth, Storage, Realtime and Functions APIs. Supavisor publishes Postgres on 5432 (session mode) and 6543 (transaction pooling).

### What is the default Supabase Studio login?

Studio is protected by HTTP basic authentication using DASHBOARD_USERNAME and DASHBOARD_PASSWORD from .env. The example file ships placeholder values, so generate new ones before the first start; run sh run.sh secrets to see the current credentials.

### How much RAM does self-hosted Supabase need?

Supabase's docs list 4 GB of RAM, 2 CPU cores and a 40 GB SSD as the minimum, and recommend 8 GB, 4 cores and 80 GB or more. The stack runs around ten containers, so it is much heavier than a single Postgres database.

### Is self-hosted Supabase free?

Yes. Supabase is open source under the Apache-2.0 license and the self-hosted stack has no license fee. Supabase Cloud adds managed backups, branching and support, with a free tier and paid plans.

### What is missing in self-hosted Supabase compared to Supabase Cloud?

Self-hosted Supabase has one project per stack, and you operate backups, scaling, upgrades and monitoring yourself. Some platform features, such as managed point-in-time recovery and multiple projects in one dashboard, are Cloud-only.

### Supabase vs Firebase?

Supabase is built on PostgreSQL, so you get SQL, relations, row-level security and a database you can self-host or move anywhere. Firebase is a proprietary Google service built on NoSQL document stores. Supabase is the usual open source Firebase alternative.

Prefer not to do it yourself? [appsgit installation help](https://appsgit.com/services/install) installs it on your server for a fixed quote.

---

Canonical page: https://appsgit.com/guides/supabase
Source: appsgit (https://appsgit.com), the app store for github. Data from the GitHub API, refreshed nightly.
Machine access: JSON API https://appsgit.com/api/v1/apps (OpenAPI: https://appsgit.com/openapi.json), MCP server https://mcp.appsgit.com/mcp, full index https://appsgit.com/llms-full.txt.
