Updated Nov 5, 20266 min read

How to Self-Host Supabase in 2026: Docker Setup, Security and What You Operate

Supabase can run on your own server with Docker Compose. The services in the stack, the setup steps, the secrets and hardening the defaults leave to you, what running it in production involves, and the alternative of running Postgres in your own cloud account behind your own backend.

Teams self-host Supabase for three reasons: data has to stay in their own infrastructure for compliance, they want to avoid usage-based bills as the project grows, or they want the Supabase developer experience on a server they already run. Supabase supports this with an official Docker Compose setup, and it works, on the understanding that you are now operating a dozen services, not one database.

This guide covers what is in the stack, how to set it up, what the defaults leave insecure, and what running it in production involves. It also covers a common alternative, running Postgres in their own cloud account and writing the backend pieces they actually use.

The self-hosted Supabase stack

The official Docker Compose configuration runs these services:

ServiceWhat it does
PostgresThe database, version 17 by default
EnvoyAPI gateway in front of every service, with Kong available as an optional override that is being phased out
AuthUser sign-up, login, sessions and JWTs
PostgRESTREST API generated from the database schema
RealtimeBroadcasts database changes and messages over WebSockets
StorageFile API backed by local disk or S3-compatible storage
imgproxyImage transformations for Storage
Edge RuntimeDeno-based runtime for Edge Functions
SupavisorPostgres connection pooler
Studio and postgres-metaThe dashboard and the API it uses to manage Postgres
Logflare and VectorLog collection and analytics, in an optional logging override

Several pieces are standard open source projects: PostgREST generates the REST API and Envoy is the gateway, so their own docs are the reference when debugging them.

Setting it up

The setup lives in the docker directory of the Supabase repository. A bootstrap script installs Docker if needed, copies that directory into a project folder, asks for the public URLs and generates secrets and API keys:

~
$ sh setup.sh --project-dir my-supabase$ cd my-supabase$ docker compose pull$ docker compose up -d

Without the script, the manual path is copying .env.example to .env and filling in every secret yourself. The values that matter most are POSTGRES_PASSWORD, JWT_SECRET and the keys derived from it, the dashboard username and password, and the encryption keys for Realtime, Vault and postgres-meta. Docker Compose then runs the services, and Studio is reachable through the gateway.

Hardening the defaults

The repository's own README states that the default configuration is not secure for production. Before real users arrive:

  • Replace every default password, secret and key in .env, and keep .env out of version control.
  • Put an HTTPS reverse proxy in front of the gateway. The repo includes Caddy and nginx overrides.
  • Review CORS and restrict network access so Postgres and internal services are not exposed.
  • Configure SMTP so Auth can send confirmation and password reset emails.
  • Move Storage from local disk to S3-compatible object storage.
  • Set DISABLE_SIGNUP and the email auto-confirm settings to match how users should join.

What running it in production involves

Backups. Nothing backs up the database for you. A cron job with pg_dump to object storage is the minimum, and point-in-time recovery needs WAL archiving with a tool such as pgBackRest or WAL-G.

Upgrades. Supabase ships self-hosted releases with an update.sh script and a changelog that regularly flags one-way migrations and security fixes. The October 2026 release, for example, included Storage migrations that cannot be rolled back. Each upgrade means a backup, reading the changelog and a maintenance window.

Availability. The Compose setup runs on one host. A second host, failover for Postgres, and load balancing are things you design and build.

Features. Some features of the hosted platform, such as branching, are not part of the self-hosted stack.

Support. Self-hosted Supabase is community-supported through GitHub Discussions and Discord.

For a team that wants Supabase's APIs and dashboard on its own server and has someone to own that host, this is a reasonable trade. For a team that mostly uses the Postgres database and a few API endpoints, it is a lot of moving parts to keep secure.

The alternative: Postgres in your own cloud, with Encore

Encore

Many projects self-hosting Supabase use it for Postgres, auth and a handful of endpoints.

Encore is infrastructure from code for TypeScript and Go, with a platform that provisions and deploys into your own AWS or GCP account, so the database runs as RDS for PostgreSQL or Cloud SQL in your account, and the API is code you write, with buckets, Pub/Sub and cron declared alongside it, as described in the AWS infrastructure docs.

The Infrastructure page in the Encore dashboard with a database's configuration panel open, showing fields for vCPUs, memory, storage, availability type, max connections and backups.
Each provisioned resource can be reviewed and its configuration edited per environment in the Encore dashboard. The screenshot shows a GCP Cloud SQL database.

Set up the app

Get started
brew install encoredev/tap/encore &&
encore app create
Copy

Run in your terminal to get started locally.

~
$ encore app create notes --example=ts/empty$ cd notes && mkdir notes

An endpoint backed by Postgres, the part of Supabase most apps lean on:

// notes/encore.service.ts import { Service } from "encore.dev/service"; export default new Service("notes");
// notes/notes.ts import { api } from "encore.dev/api"; import { SQLDatabase } from "encore.dev/storage/sqldb"; // RDS for PostgreSQL on AWS, Cloud SQL on GCP, a local Postgres under encore run. const db = new SQLDatabase("notes", { migrations: "./migrations" }); interface Note { id: number; body: string; } export const create = api( { expose: true, method: "POST", path: "/notes" }, async ({ body }: { body: string }): Promise<Note> => { const row = await db.queryRow<Note>` INSERT INTO notes (body) VALUES (${body}) RETURNING id, body`; return row!; }, );
-- notes/migrations/1_create_notes.up.sql CREATE TABLE notes (id BIGSERIAL PRIMARY KEY, body TEXT NOT NULL);

encore run starts Postgres locally, and on deploy the RDS instance gets Multi-AZ, 7-day automated backups, encryption at rest and placement in a private subnet by default, which covers the backup and availability work from the list above. Existing data moves over with pg_dump and pg_restore, since both sides are standard Postgres. The database API is in the TypeScript database docs, and auth is added with an auth handler as covered in the authentication docs.

An AI coding agent can build the endpoints that replace PostgREST calls one at a time and test each against the local Postgres.

Connecting the AWS or GCP account is a one-time step covered in the own-cloud deployment guide.

Best fit: Teams self-hosting Supabase mainly for data control, who want managed Postgres in their own AWS or GCP account.

Frequently asked questions

Can you self-host Supabase?

Yes. Supabase publishes an official Docker Compose setup with Postgres, Auth, PostgREST, Realtime, Storage, Studio, Edge Runtime, an Envoy API gateway, Supavisor and logging services. Self-hosted Supabase is community-supported, and you are responsible for security, backups, upgrades and scaling.

Is self-hosted Supabase free?

The software is open source under the Apache 2.0 license and free to run. You pay for the servers, storage, bandwidth and the engineering time to operate, secure, back up and upgrade the stack.

What do you need to change before running self-hosted Supabase in production?

Replace every default password and secret in .env, including POSTGRES_PASSWORD, JWT_SECRET, the API keys and the dashboard credentials, put an HTTPS proxy in front, review CORS and network access, configure SMTP for auth emails, move Storage to S3-compatible object storage and set up database backups.

What is an alternative to self-hosting Supabase on AWS?

Run managed Postgres in your own AWS account and write the backend yourself. With Encore, you declare the database with new SQLDatabase() in TypeScript or Go and write endpoints with api(), and deploying creates RDS for PostgreSQL, the services and the networking in your account, with no Supabase stack to operate.

Deploy to your cloud on AWS and Google Cloud
without managing infrastructure

Encore lets developers and agents define application infrastructure directly in code, then automatically provisions it from local development to production in your AWS or GCP account.

~/orders — claude
Claude Code
Claude Code v2.1.180Opus 5.5~/orders