Deployment guide

Supabase vs Appwrite: Choosing Your Open-Source BaaS on a VPS

Deploy on a VPS Cloud →

Supabase vs Appwrite: Choosing Your Open-Source BaaS on a VPS

Comparison12 min read8 steps

Supabase and Appwrite are the two most popular open-source BaaS platforms to replace Firebase without depending on a proprietary cloud. Both deploy with Docker on a VPS, but their architectures, resource requirements, and ideal use cases differ significantly. This guide compares both platforms point by point to help you choose the right one for your project — and your server.

Contents· What is a BaaS and why self-host it?1/14
  1. 01What is a BaaS and why self-host it?
  2. 02Supabase vs Appwrite — 12-criteria comparison
  3. 03Deploying Supabase on a VPS
  4. 04Deploying Appwrite on a VPS
  5. 05Authentication — Provider Comparison and OAuth
  6. 06Serverless Functions — Deno vs 30+ Runtimes
  7. 07Real-Time and File Storage
  8. 08Appwrite: 503 error on first launch — wait for migrations
  9. 09Supabase: 502 Bad Gateway from gateway on startup — normal behavior
  10. 10Appwrite 2.0: migrating from 1.x — procedure and breaking changes
  11. 11Supabase 0.8.0: Kong to Envoy — impact and TLS migration
  12. 12Decision guide — Supabase or Appwrite for your project?
  13. 13Common errors and fixes — both platforms
  14. 14Conclusion: two excellent BaaS platforms, two different philosophies

What is a BaaS and why self-host it?

A Backend-as-a-Service (BaaS) bundles everything a modern application needs on the server side into a single product: database, authentication, file storage, serverless functions, and real-time communication. Firebase popularized this model, but its proprietary nature raises concerns about cost, GDPR compliance, and vendor lock-in.

Self-hosting an open-source BaaS on your own VPS gives you full control over your data, eliminates per-request fees, and lets you meet data residency requirements. Supabase and Appwrite are the two most mature solutions in this space.

Supabase vs Appwrite — 12-criteria comparison

Scroll the table

CriterionSupabaseAppwrite
DatabasePostgreSQLMariaDB (≤ 1.8), PostgreSQL (2.0+)
Minimum RAM4 GB2 GB
Recommended production RAM8 GB4 GB
Number of containers~13~19
Main port8000 (Envoy since 0.8.0, Kong before)80 / 443 (Traefik)
Admin port3000 (Studio)80 / console (Traefik)
Included servicesAuth, PostgREST, Realtime, Storage, Edge Functions, StudioAuth, Databases, Storage, Functions, Messaging, Realtime
Auth providers15+30+
Functions runtimeDeno only30+ runtimes (Node, Python, PHP, Go, Dart, Ruby, Bun…)
Client SDKsJS, Python, Swift, Kotlin, Flutter, C#JS, iOS, Android, Flutter, React Native, Web
RealtimeWebSocket via Realtime serviceWebSocket via Appwrite Realtime
LicenseApache 2.0BSD 3-Clause

Deploying Supabase on a VPS

  1. Step 1 — Server prerequisites

    Provision a VPS with at least 4 GB of RAM (8 GB recommended for production), Docker and Docker Compose installed. Open port 8000 (API gateway) and port 3000 (Studio) in your firewall. A minimum 40 GB SSD disk is recommended for PostgreSQL.

  2. Step 2 — Clone the repository and configure the environment

    Clone with git clone --depth 1 https://github.com/supabase/supabase, enter supabase/docker and copy .env.example to .env. Set at minimum POSTGRES_PASSWORD, JWT_SECRET, ANON_KEY and SERVICE_ROLE_KEY.

  3. Step 3 — Start the stack

    Run docker compose up -d. Full startup takes 60 to 120 seconds. With Supabase 0.8.0+, Envoy (not Kong) serves port 8000. Check status with docker compose ps and wait until all containers are healthy.

  4. Step 4 — Verify the installation

    Access Studio at http://your-ip:3000. Test a simple API call with curl http://your-ip:8000/rest/v1/ -H "apikey: YOUR_ANON_KEY". An empty JSON response {} confirms PostgREST is responding correctly through the gateway.

Deploying Appwrite on a VPS

  1. Step 1 — Server prerequisites

    Appwrite is lighter at bootstrap: 2 GB of RAM is enough to test, but 4 GB is recommended for production. Its ~19 containers include Traefik as a reverse proxy. Ports 80 and 443 must be open.

  2. Step 2 — Run the interactive installer

    Run docker run -it --rm --volume /var/run/docker.sock:/var/run/docker.sock --volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw --entrypoint="install" appwrite/appwrite:latest. The wizard asks for your domain and HTTP/HTTPS ports, and generates a docker-compose.yml tailored to your environment.

  3. Step 3 — Wait for database migrations

    On first startup, Appwrite runs its migrations. This process takes 2 to 5 minutes and results in temporary 503 errors — this is expected. Follow progress with docker compose logs -f appwrite.

  4. Step 4 — Create the admin account

    Once migrations are complete, access http://your-domain/console. Create your first admin account, then your first project.

Authentication — Provider Comparison and OAuth

Both platforms handle email/password and phone number (SMS OTP) authentication. Appwrite supports 30+ OAuth2 providers versus 15+ for Supabase.

Supabase uses GoTrue as its authentication service — a lightweight daemon written in Go. Appwrite integrates its own Auth service configurable per project from the web console.

Important post-2.0 note: issue #13547 (https://github.com/appwrite/appwrite/issues/13547) reports that password reset and email invitations are broken in Appwrite 2.0 self-hosted. A fix is expected in 2.0.1. Test these flows in a staging environment before migrating your production instance.

Serverless Functions — Deno vs 30+ Runtimes

Supabase Edge Functions run exclusively on Deno — the modern JavaScript/TypeScript runtime. Deno offers security by default (explicit permissions), native TypeScript support, and a growing module ecosystem.

Appwrite Functions support 30+ runtimes: Node.js, Python, PHP, Ruby, Go, Dart, .NET, Java, Kotlin, Swift, Bun, and more. Each runtime is an isolated Docker container. This flexibility is a major advantage for polyglot teams.

Appwrite 2.0 note: the _APP_LOGGING_PROVIDER and _APP_LOGGING_CONFIG_REALTIME environment variables are removed in 2.1.0. Remove them from your .env before upgrading to avoid startup errors.

Real-Time and File Storage

Real-time. Both platforms use WebSockets. Supabase exposes PostgreSQL changes in real time via its Realtime service (logical replication). Appwrite Realtime covers events on documents, files, and teams — less tied to the underlying database and therefore more portable.

A note with Supabase: the Realtime service sometimes starts before PostgREST is fully initialized, generating the error could not connect to the database. Restarting the realtime container usually resolves this.

Storage. Supabase Storage uses an S3-compatible API with RLS access policies directly from PostgreSQL. Appwrite Storage offers team- and user-based permissions, simpler to configure.

Appwrite: 503 error on first launch — wait for migrations

If the Appwrite console shows a 503 error or remains inaccessible in the first few minutes, do not restart the containers. Appwrite automatically runs its database migrations on first startup — a process that takes 2 to 5 minutes. Follow progress with docker compose logs -f appwrite and wait for Migrations completed. Restarting containers during this phase will corrupt the database and require a full reinstall.

Supabase: 502 Bad Gateway from gateway on startup — normal behavior

The Supabase API gateway (Kong up to 0.7.x, Envoy from 0.8.0) may return 502 errors during the first 30 to 60 seconds after docker compose up -d. This is normal and transient — the gateway waits for PostgREST, GoTrue and other services to be ready. Wait until docker compose ps shows all containers as healthy. If 502s persist beyond 2 minutes, inspect logs with docker compose logs supabase-rest-proxy (0.8.0+) or docker compose logs kong (older versions).

Appwrite 2.0: migrating from 1.x — procedure and breaking changes

Appwrite 2.0 was released on September 7, 2026 (source: https://appwrite.io/changelog/entry/2026-09-07). It is a major update that migrates the persistence engine from MariaDB to PostgreSQL in an irreversible way — rolling back to 1.x is not possible after migration.

Mandatory migration path. You must first upgrade to version 1.9.6 before moving to 2.0. Skipping this intermediate step makes migration impossible. Recommended procedure:

1. Back up all your Docker volumes: docker compose down then copy your Appwrite data directory.
2. First upgrade to 1.9.6: update the image in your docker-compose.yml to appwrite/appwrite:1.9.6, then run docker compose pull && docker compose up -d.
3. Wait for 1.9.6 migrations to complete (docker compose logs -f appwrite | grep -i migrat).
4. Upgrade to 2.0: change the image to appwrite/appwrite:2.0, then run docker compose pull && docker compose up -d.
5. PostgreSQL migrations run automatically on first 2.0 startup — do not stop containers during this process.

Breaking changes. Issue #13547 reports password reset and email invitations are broken in Appwrite 2.0 self-hosted. Test these flows in pre-production before migrating your main instance. The _APP_LOGGING_PROVIDER and _APP_LOGGING_CONFIG_REALTIME variables are removed in 2.1.0 — remove them from your .env now. The migration is irreversible: once on 2.0, only a full restore from backup allows returning to 1.x.

Supabase 0.8.0: Kong to Envoy — impact and TLS migration

Supabase docker-compose 0.8.0, released August 11, 2026 (source: https://github.com/supabase/supabase/blob/master/docker/CHANGELOG.md), replaces Kong with Envoy as the API gateway. This architectural change is transparent for most deployments, but carries a TLS breaking change: the TLS listener on port 8443 disappears.

What changes concretely. If your reverse proxy or health check scripts made direct HTTPS requests to https://your-ip:8443, those calls will silently fail after the update. Envoy does not re-expose this port. TLS termination must now be handled exclusively by your front-end reverse proxy.

Migration steps. Before upgrading to 0.8.0:
- Audit all references to port 8443 in your deployment scripts, health checks, and firewall rules.
- Replace them with calls to port 8000 over HTTP from the internal network, with TLS terminated by the reverse proxy.
- After docker compose pull && docker compose up -d, verify that docker compose ps no longer lists a kong service and that an Envoy-based service is present and healthy.

Kong-related environment variables (KONG_HTTP_PORT, KONG_HTTPS_PORT, KONG_*) in your .env are now ignored but do not prevent startup — you may remove them to clean up your configuration.

Decision guide — Supabase or Appwrite for your project?

Choose Supabase if: your application is web-first, your team knows PostgreSQL, you're migrating from Firebase, or you need an auto-generated REST API from your database schema (PostgREST).

Choose Appwrite if: you're building a mobile (iOS/Android) cross-platform application, your team works in multiple languages and wants to choose its function runtimes, or you prefer a more accessible admin interface without deep SQL knowledge.

On a VPS with 4 GB RAM, Appwrite offers more headroom (requires 2 GB, recommends 4 GB) versus Supabase which uses its 4 GB minimum from startup.

In 2026, both platforms are evolving rapidly. Appwrite 2.0 unifies its database on PostgreSQL — reducing Supabase's historical advantage on that point — while Supabase modernizes its gateway with Envoy. For a new installation, both are equivalent on the database question. For an existing installation, plan a maintenance window and test critical flows before any major update.

Common errors and fixes — both platforms

  • Supabase — 502 Bad Gateway (gateway): wait 30-60s for all services to be healthy. If persistent: docker compose restart supabase-rest-proxy (0.8.0+) or docker compose restart kong (< 0.8.0).
  • Supabase — Realtime could not connect to the database: restart with docker compose restart realtime.
  • Supabase — Invalid JWT: check that ANON_KEY and SERVICE_ROLE_KEY are signed with the same JWT_SECRET as in .env.
  • Supabase 0.8.0 — port 8443 unreachable: the Kong TLS listener was removed with Envoy. Remove direct calls to port 8443 and delegate TLS to the front-end reverse proxy.
  • Appwrite — 503 on startup: migrations in progress (2-5 min). Do not restart containers.
  • Appwrite — docker compose down -v: DANGER — deletes all data volumes. Never run in production.
  • Appwrite — function timeout: cold start of an unused runtime may exceed the default timeout. Increase the limit in project settings.
  • Appwrite 2.0 — migration blocked: you must pass through 1.9.6 before 2.0. Skipping this step makes migration impossible. Restore your backup and start over.
  • Appwrite 2.0 — password reset / invitations broken: issue #13547 confirmed in self-hosted. Test these flows before going to production.
  • Appwrite 2.1.0 — removed variables: remove _APP_LOGGING_PROVIDER and _APP_LOGGING_CONFIG_REALTIME from .env before upgrading to avoid startup errors.

Conclusion: two excellent BaaS platforms, two different philosophies

Supabase and Appwrite are both solid choices for self-hosting an open-source BaaS on your VPS. Supabase shines through its PostgreSQL depth, auto-generated API, and polished Studio. Appwrite stands out for its relative lightness, the richness of its function runtimes, and the quality of its mobile SDKs.

In September 2026, both platforms are undergoing structural updates: Appwrite 2.0 adopts PostgreSQL irreversibly, Supabase 0.8.0 switches from Kong to Envoy. Plan your migrations with a full backup, a test environment, and validation of critical flows — especially email authentication for Appwrite 2.0. In both cases, a dedicated VPS with at least 4 GB of RAM and automated volume backups is the foundation of a reliable deployment. Starting from 99 DH/month on ServOrbit.

Host your BaaS on a VPS you control

Whether you choose Supabase or Appwrite, both deserve a stable, fast, and backed-up VPS. Our Cloud VPS plans start at 4 GB RAM with daily snapshots included — exactly what you need to run your open-source backend in production.

Need help?

Browse our help center and FAQ, or reach our team — callback, WhatsApp or email. Support in French, English and Arabic.

Message us on WhatsAppopens in a new tab