Deployment guide

Supabase vs Appwrite: which self-hosted backend for your VPS?

Deploy on a VPS Cloud →

Comparison9 min read

Supabase vs Appwrite: which self-hosted backend for your VPS?

Supabase and Appwrite are the two heavyweights of the open-source backend-as-a-service. Both provide authentication, database, storage and functions, but with opposing philosophies: Supabase is centered on PostgreSQL, Appwrite on a developer-oriented multi-database abstraction. Here's how to choose and self-host them on your VPS.

Why host your BaaS backend yourself

A BaaS saves you from rewriting authentication, permissions, file storage and real-time APIs for every project. But the cloud offerings of Supabase and Appwrite bill by usage (rows read, storage, MAU) and limit access to the underlying database. By self-hosting on a VPS, you regain direct SQL access, predictable fixed costs and total sovereignty over user data, which is decisive for compliance. Supabase relies entirely on PostgreSQL and exposes an auto-generated REST/GraphQL API plus real-time via the WAL. Appwrite abstracts persistence behind its own API and natively includes multi-runtime serverless functions, a permission system granular down to the document, and an image transcoding engine.

The advantages of self-hosting a BaaS

  • Direct SQL access to PostgreSQL (Supabase) for queries, views and migrations with no intermediary.
  • Fixed costs tied to the VPS, with no billing by number of rows read or active users.
  • User data and files hosted locally: control over data residency.
  • Customization of serverless functions with your own runtimes and dependencies.
  • No cold start or execution quotas imposed by a third-party cloud.
  • Integration into the private Docker network with your other internal services.
CriterionSupabaseAppwrite
DatabaseNative PostgreSQL (full SQL access)Own abstraction (MariaDB underneath)
Exposed APIAuto-generated REST + GraphQL (PostgREST)REST + GraphQL + multi-language SDK
Real-timeSubscriptions on PostgreSQL changesReal-time channels per collection
Serverless functionsEdge Functions (Deno)Multi-runtime Functions (Node, Python, PHP, Dart…)
PermissionsPostgreSQL Row Level SecurityPermissions per document and per role
Container architectureComposed stack (~10 services)Composed stack around a main container
Recommended self-hosted RAM4 GB minimum2 to 4 GB
Target audienceTeams comfortable with SQLDevelopers seeking a unified API

Prerequisites for a healthy deployment

Supabase self-hosted is a stack composed of about ten containers (Postgres, GoTrue, PostgREST, Realtime, Storage, Kong, Studio…). Plan for a VPS of at least 2 vCPU and 4 GB of RAM, with 20 GB of SSD/NVMe disk for the database and files. Appwrite is more modest at bootstrap: 2 vCPU and 2 GB of RAM are enough to start, but move up to 4 GB as soon as the serverless functions run, because each execution launches a container. In both cases: Docker Compose v2 mandatory, a dedicated domain (api.mydomain.com), and a reverse proxy handling HTTPS and WebSockets (indispensable for real-time).

Deploy your self-hosted backend

01

Get the official stack

For Supabase: git clone --depth 1 https://github.com/supabase/supabase then copy docker/.env.example to .env. For Appwrite, installation is done via docker run of an init script that generates the docker-compose.yml and the .env.

02

Generate and harden the secrets

This is the most critical step. You must regenerate POSTGRES_PASSWORD, JWT_SECRET, ANON_KEY and SERVICE_ROLE_KEY for Supabase; the default keys are public. For Appwrite, set _APP_OPENSSL_KEY_V1 and a strong admin password.

03

Configure the domain and public URLs

Set API_EXTERNAL_URL=https://api.mydomain.com and SITE_URL on the Supabase side, or _APP_DOMAIN and _APP_DOMAIN_TARGET on the Appwrite side, so that OAuth redirects and email links are correct.

04

Launch the stack

Run docker compose up -d. Watch docker compose ps: all services must reach healthy. Supabase Studio is served via Kong on port 8000, the Appwrite interface on the internal 80/443.

05

Put Kong/Appwrite behind HTTPS

With Traefik or Caddy, route api.mydomain.com to the exposed port and enable WebSocket passthrough (Upgrade/Connection) for real-time. Force the redirect from HTTP to HTTPS.

06

Initialize and test

Create your first project/user via the Studio (Supabase) or the console (Appwrite), then test auth and a query from a client SDK. Check that the real-time subscriptions properly relay the changes.

For Supabase in production, never store the database on the default Docker volume: mount a dedicated volume and schedule encrypted pg_dumps to external storage, because restoring from a corrupted volume is unmanageable. Also enable Row Level Security on all your tables from creation, otherwise your ANON_KEY grants full access. On the Appwrite side, limit the function runtime and the number of concurrent execution containers via _APP_FUNCTIONS_* to prevent a spike of requests from saturating the VPS.

Your complete backend on a dedicated VPS

Deploy Supabase or Appwrite on a ServOrbit Cloud VPS with Docker, NVMe storage and scalable resources. The preconfigured template saves you the installation step.

Need help?

Browse our help center and FAQ, or write to our team — support in French, English and Arabic.