Appwrite: A Self-Hosted, Open-Source Alternative to Firebase
Appwrite is an open-source backend server that provides authentication, databases, file storage, serverless functions, and real-time event subscriptions. It runs entirely in Docker on infrastructure you control, which means your data stays on your servers and your costs are determined by your server bill rather than per-read and per-write metering.
Why self-host instead of using Firebase
Firebase's pay-as-you-go model works well for small applications but becomes difficult to predict as usage scales. Costs are tied to the number of Firestore reads, writes, and deletes, so a sudden traffic spike directly translates to a larger bill. Because application code is written against Firebase-specific APIs, migrating to another provider later is a substantial engineering effort.
For applications in healthcare, finance, or jurisdictions with strict data sovereignty requirements, storing user data on Google's servers may not be acceptable regardless of cost. Appwrite's self-hosted model lets you choose any server in any location.
The tradeoff is infrastructure responsibility. You manage the server, updates, and backups. For many teams this is a reasonable exchange for predictable costs, data ownership, and freedom from proprietary lock-in.
Feature overview
Appwrite covers the core services most applications need:
- Auth: email and password, anonymous login, magic URLs, and over 30 OAuth2 providers
- Databases: document-style collections backed by MariaDB, with a web console for schema management and permissions
- Storage: file upload and management with encryption, compression, and real-time image transformations
- Functions: serverless functions in over 30 languages and runtimes
- Realtime: WebSocket-based subscriptions to any Appwrite event
- Messaging: push notifications, email, and SMS under a unified API
Installing Appwrite with Docker
Appwrite ships as a Docker Compose stack. The installation process creates the configuration files and then starts all services.
Prerequisites
Docker and Docker Compose are required. The setup is identical across Windows, macOS, and Linux.
Running the installer
From a directory where the configuration files should be placed:
Check the official documentation for the current version tag before running. The --volume /var/run/docker.sock mount gives the installer access to the host Docker engine so it can create the service containers. The appwrite volume mount is where the installer writes docker-compose.yml and .env.
The installer prompts for HTTP port (default 80), HTTPS port (default 443), a secret API key, a hostname (use localhost for local development), and a CNAME hostname. Accepting defaults is fine for development. The installer writes the configuration files to ./appwrite/.
Starting the services
This starts the Appwrite server, database, Redis, and supporting services in the background. First-run image downloads take a few minutes. After that, the console is available at http://localhost.
Setting up a project and database
Creating a project
After creating an admin account at http://localhost, click Create project in the dashboard. The project ID shown at the top of the project dashboard is needed later to connect a client application.
Registering a web platform
Appwrite rejects requests from origins not registered with the project. Under Add platform, select New Web App, enter localhost as the hostname, and save. This authorizes requests from the local development server.
Creating a database and collection
Under Databases, create a database. Inside it, create a collection. Collections are equivalent to tables. For a to-do application, a list collection with four string attributes covers the required fields: title (size 200, required), content (size 200, required), userId (size 36, required), and authorEmail (size 200, required).
Configuring permissions
Appwrite's permission system controls read, create, update, and delete access per role.
Under the collection Settings, add two roles. For the Any role (unauthenticated users), enable only Read. For the Users role (authenticated users), enable Create, Read, Update, and Delete. This gives public read access to all to-do items and full write access to logged-in users, with no backend code required.
Connecting a front-end application
Environment variables
The client application needs the Appwrite endpoint, project ID, database ID, and collection ID. For a Vite-based React project:
The project, database, and collection IDs are in their respective settings pages in the Appwrite console.
Real-time sync
With the Appwrite Web SDK configured, the application can use Auth for sign-up and login, the Databases API to create and fetch documents, and the Realtime API to subscribe to collection changes. Opening the application in two browser tabs demonstrates this: creating, updating, or deleting a to-do in the logged-in tab appears immediately in the other tab without a page refresh.
Final thoughts
Appwrite offers a compelling path for teams that want Firebase-style developer convenience without the pricing model or data residency tradeoffs. The Docker-based installation is straightforward, the permission system eliminates most custom backend authorization code, and real-time subscriptions work without additional infrastructure.
The main operational cost is server management. Keeping the Docker stack updated, running backups, and monitoring uptime fall to you. For most applications, a $10 to $20 monthly VPS handles substantial traffic at predictable cost, and the official documentation covers production hardening, upgrades, and scaling guidance.