Pourquoi auto-héberger Appwrite sur un VPS
Appwrite regroupe en une seule plateforme tout ce dont une application a besoin côté serveur : authentification avec plus de 30 méthodes OAuth, base de données documentaire avec permissions granulaires, stockage de fichiers avec transformation d'images, fonctions serverless dans plusieurs langages, et messaging. Sa version cloud facture par usage et par ressources ; en self-hostant sur un VPS, vous déployez l'ensemble via Docker et vous le pilotez depuis une console web élégante, sans plafond.
C'est particulièrement adapté aux développeurs Flutter, React Native ou web qui veulent un backend prêt à l'emploi avec des SDK officiels, tout en gardant les données et la logique sur leur propre infrastructure. Vous contrôlez les fonctions, les clés API et les permissions, et vous évoluez à votre rythme — sans subir les quotas ou les hausses tarifaires d'un cloud public.
Les bénéfices concrets d'un Appwrite auto-hébergé
- Backend tout-en-un : Auth, Databases, Storage, Functions et Messaging dans une console unique.
- SDK officiels pour Flutter, React Native, Web, Android, iOS, Node, Python et plus.
- Plus de 30 fournisseurs OAuth intégrés (Google, GitHub, Apple...) sans code.
- Fonctions serverless self-hosted : exécutez votre logique métier sans service externe.
- Permissions granulaires au niveau document et collection, gérées depuis la console.
- Pas de facturation à l'exécution ni de quota d'utilisateurs : forfait VPS fixe.
- Données hébergées sur votre infrastructure : conformité RGPD facilitée, aucune dépendance cloud tierce.
- Realtime intégré : abonnez-vous aux changements de documents, de fichiers et d'état de session via WebSocket.
Architecture interne : ce que Docker lance réellement
Avant d'installer, il est utile de savoir ce qu'Appwrite orchestre. L'installateur officiel génère un docker-compose.yml avec une vingtaine de services au minimum :
- appwrite — le serveur API principal (PHP, expose le port 80/443 via Traefik).
- appwrite-console — la console web d'administration (React, servie par le même domaine sur /).
- appwrite-realtime — le service WebSocket pour les abonnements temps réel.
- appwrite-worker-* — une série de workers pour les tâches asynchrones : envoi d'e-mails, webhooks sortants, nettoyage de fichiers temporaires, etc.
- appwrite-executor — le runtime d'exécution des Functions serverless (Docker-in-Docker).
- mariadb — la base relationnelle interne (utilisateurs, projets, règles de permission).
- redis — le cache et la file de tâches (jobs workers, sessions, rate-limiting).
- traefik — le reverse proxy intégré qui gère le routage HTTPS et les certificats Let's Encrypt.
Pour un VPS de développement, seul le nœud core est strictement nécessaire : API, Console, MariaDB, Redis et Traefik. Les workers et l'executor sont indispensables en production si vous utilisez les Functions, les webhooks ou l'envoi d'e-mails. Comptez 4 Go de RAM minimum pour cette stack complète : MariaDB et les workers d'arrière-plan se partagent la mémoire disponible, et chaque invocation de Function démarre son propre conteneur éphémère.
Prérequis matériels et logiciels
Pour une instance de développement ou de test, 2 vCPU et 4 Go de RAM avec 40 Go de SSD suffisent. Pour de la production avec des fonctions serverless actives et plusieurs apps clientes, visez 4 vCPU, 8 Go de RAM et 80 Go de SSD — chaque invocation de Function démarre son propre conteneur éphémère, ce qui pèse sur le disque et le CPU.
Côté logiciel : Ubuntu 22.04 ou 24.04 LTS, Docker CE et Docker Compose v2 (Appwrite gère son propre Traefik pour le routage et le SSL), et un nom de domaine pointant vers l'IP du VPS — par exemple api.monapp.com. Les ports 80 et 443 doivent être libres et ouverts dans ufw pour que Traefik obtienne les certificats Let's Encrypt via le challenge ACME.
Un point sur le stockage. Les Functions génèrent des images Docker intermédiaires qui s'accumulent sur le SSD. Sans purge régulière, une instance qui tourne plusieurs mois peut saturer son disque. Prévoyez une tâche docker system prune --volumes -f planifiée en cron hebdomadaire, et surveillez l'espace libre avec df -h.
Déployer Appwrite self-hosted avec Docker
Préparer le VPS et ouvrir les ports
Installez Docker CE et Docker Compose v2, puis ouvrez les ports nécessaires :
ufw allow 80/tcp ufw allow 443/tcp ufw enableFaites pointer votre domaine (ex.
api.monapp.com) vers l'IP du VPS via un enregistrement A. Attendez la propagation DNS avant de lancer l'installateur — Traefik a besoin que le domaine résolve réellement pour passer le challenge ACME.Lancer l'installateur interactif officiel
Exécutez l'installateur en une ligne :
docker run -it --rm \ --volume /var/run/docker.sock:/var/run/docker.sock \ --volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \ --entrypoint="install" \ appwrite/appwriteL'assistant vous demande le domaine principal, le port HTTP (80), le port HTTPS (443), un e-mail pour Let's Encrypt et quelques options. Il génère un
docker-compose.ymlet un fichier.envavec les secrets générés aléatoirement. Ne touchez pas à ces secrets à la main — changez-les uniquement via les variables d'environnement du.env.Vérifier la configuration du domaine et du SSL
Après le démarrage (
docker compose up -d), attendez 30 à 60 secondes que Traefik émette le certificat. Vérifiez :curl -I https://api.monapp.com/v1/healthLa réponse doit être
HTTP/2 200avec uncontent-type: application/json. Si Traefik n'a pas encore de certificat, vous obtenez une erreur TLS — c'est normal pendant les premières secondes. En cas de blocage prolongé, vérifiez que les ports 80/443 ne sont pas filtrés par un pare-feu amont et que le domaine résout vers la bonne IP (dig api.monapp.com).Créer le compte administrateur et le premier projet
Ouvrez
https://api.monapp.comdans votre navigateur. Appwrite vous invite à créer le compte administrateur racine lors du premier accès — ce compte est le seul à avoir accès aux réglages de la plateforme. Depuis la console, créez un projet, ajoutez une plateforme (Web, Flutter, Apple…) en déclarant le hostname autorisé, et récupérez l'ID de projet. Ces informations alimentent l'initialisation du SDK côté client :npm install appwriteimport { Client } from 'appwrite'; const client = new Client() .setEndpoint('https://api.monapp.com/v1') .setProject('<votre-project-id>');Durcir la configuration de production
Ouvrez le fichier
.envgénéré par l'installateur et ajustez les variables suivantes :-
_APP_OPTIONS_ABUSE=enabled— active le rate-limiting intégré par IP.
-_APP_OPTIONS_FORCE_HTTPS=enabled— redirige toutes les requêtes HTTP vers HTTPS.
-_APP_SMTP_HOST/_APP_SMTP_PORT/_APP_SMTP_SECURE/_APP_SMTP_USERNAME/_APP_SMTP_PASSWORD— configurez votre relais SMTP pour les e-mails de vérification et de réinitialisation de mot de passe.
-_APP_CONSOLE_WHITELIST_ROOT=disabledsi vous souhaitez permettre l'inscription libre à la console (non recommandé en prod) ; laissez-le surenabledet renseignez_APP_CONSOLE_WHITELIST_EMAILSavec les adresses autorisées.Redémarrez les services après modification :
docker compose up -d.Configurer les sauvegardes automatisées
Deux volumes Docker contiennent toutes les données persistantes d'Appwrite :
-
appwrite-mariadb— la base de données (utilisateurs, projets, documents, règles).
-appwrite-uploads— les fichiers déposés par les apps clientes.Planifiez un dump quotidien :
docker exec appwrite-mariadb mysqldump \ -u appwrite -p"$MARIADB_ROOT_PASSWORD" appwrite \ > /backups/appwrite-$(date +%Y%m%d).sqlArchivez aussi le volume
appwrite-uploads(untardes données ou un snapshot de volume selon votre infrastructure). Sauvegardez également_APP_OPENSSL_KEY_V1— Appwrite l'utilise pour chiffrer les fichiers et certaines données sensibles. Sans cette clé, une restauration de base rend les contenus chiffrés illisibles.
Réseau et Traefik : ce qui se passe derrière le rideau
Traefik est le seul point d'entrée réseau d'Appwrite : il écoute sur les ports 80 et 443, gère les certificats Let's Encrypt, et route les requêtes vers le bon service interne. Cette intégration est transparente — vous n'avez pas de configuration Traefik à écrire, elle est générée par l'installateur.
Quelques points importants si vous ajoutez un reverse proxy en amont (nginx, Cloudflare Tunnel…) :
- Ne doublez pas le TLS. Si votre proxy amont termine déjà le SSL et transmet en HTTP à Appwrite, désactivez le challenge ACME en mettant _APP_OPTIONS_FORCE_HTTPS=disabled et _APP_SYSTEM_SECURITY_EMAIL_ADDRESS= à vide pour éviter que Traefik tente d'obtenir un certificat qu'il ne peut pas valider.
- Transmettez l'IP réelle. Ajoutez X-Forwarded-For et X-Real-IP dans votre proxy amont, et activez le trust des headers dans Traefik (déjà configuré par défaut dans l'installateur Appwrite).
- Ports de la console. La console web et l'API sont servies sous le même domaine : ne routez pas le port 9501 (Realtime interne) publiquement, il est géré par Traefik en interne.
Si vous placez Appwrite derrière Cloudflare en mode proxifié, passez le mode SSL de la zone en Full (strict) — en mode Flexible, nginx redirige HTTP→HTTPS, ce qui crée une boucle de redirection infinie entre Cloudflare et Traefik.
Dépannage des problèmes courants
La console affiche « Could not connect to the Appwrite API ».
Vérifiez que les variables _APP_DOMAIN et _APP_DOMAIN_TARGET dans .env correspondent exactement au domaine que vous utilisez. Un sous-domaine mal renseigné (avec ou sans www) empêche Traefik de router correctement. Relancez docker compose up -d après toute modification du .env.
Les e-mails de vérification n'arrivent pas.
Appwrite ne dispose pas de relais SMTP intégré — il faut configurer _APP_SMTP_* avec un service externe (Mailgun, Resend, votre propre serveur). Sans SMTP configuré, les e-mails sont mis en file et ignorés. Vérifiez les logs du worker appwrite-worker-mails : docker compose logs appwrite-worker-mails --tail 50.
Les Functions serverless s'exécutent en timeout.
Chaque Function démarre son propre conteneur Docker. Sur un VPS à 2 Go de RAM, le démarrage à froid dépasse souvent les 10 secondes, ce qui déclenche le timeout par défaut. Augmentez _APP_FUNCTIONS_TIMEOUT dans .env et prévoyez au moins 4 Go de RAM pour un usage en production. Surveillez aussi l'espace disque — les images de runtime restent sur le SSD après exécution.
Le certificat SSL ne se génère pas.
Traefik a besoin que les ports 80 et 443 répondent depuis l'extérieur pour passer le challenge ACME. Si un pare-feu amont (règles de sécurité de votre fournisseur VPS) bloque ces ports, le challenge échoue silencieusement. Testez depuis une machine externe : curl -I http://api.monapp.com doit répondre (même en 302), pas expirer.
MariaDB démarre mais la console affiche des erreurs de base.
Si vous avez modifié manuellement le .env entre deux démarrages, vérifiez que _APP_DB_HOST, _APP_DB_USER et _APP_DB_PASS correspondent aux valeurs du conteneur MariaDB. Un redémarrage partiel (un seul service) sans docker compose down peut laisser des conteneurs orphelins avec d'anciennes variables en mémoire.
Appwrite vs Supabase : lequel self-hoster ?
Faites défiler le tableau
| Critère | Appwrite | Supabase |
|---|---|---|
| Base de données | MariaDB, modèle documentaire | PostgreSQL natif, SQL complet |
| Approche | Orienté SDK et apps mobiles | Orienté SQL et apps relationnelles |
| Fonctions serverless | Natives, multi-langages intégrées | Edge Functions (Deno) |
| Installation | Installateur interactif officiel | Compose à configurer manuellement |
| SSL / routage | Traefik intégré, automatique | Reverse proxy externe à ajouter |
| Recherche vectorielle / IA | Non native | Native via pgvector |
| Realtime | WebSocket intégré, multi-ressources | Postgres CDC via Realtime |
| Idéal pour | Flutter, React Native, mobile-first | SQL avancé, RAG, relationnel |
| Console d'administration | Console riche et guidée | Studio centré sur les tables SQL |
Mises à jour et maintenance continue
Pour mettre à jour Appwrite, relancez l'installateur avec la nouvelle version ou modifiez le tag d'image dans docker-compose.yml et exécutez docker compose pull && docker compose up -d. Appwrite applique les migrations de schéma automatiquement au démarrage du conteneur API — aucune commande manuelle n'est nécessaire.
Planifiez également une purge hebdomadaire des images Docker orphelines pour éviter la saturation du SSD :
docker system prune --volumes -fSauvegardez _APP_OPENSSL_KEY_V1 dans un coffre séparé (gestionnaire de secrets, fichier chiffré hors du VPS). Sans cette clé, une restauration de base rend les fichiers chiffrés et certaines données sensibles définitivement illisibles — c'est le seul point de non-retour d'une installation Appwrite.
Ce template fournit le cœur — les Functions viennent ensuite
L'installeur officiel d'Appwrite génère plus de 25 conteneurs, dont des workers d'arrière-plan et un runtime d'exécution pour les Functions serverless et les Sites. Pour garder une empreinte VPS réduite, ce template ne fournit que le cœur autosuffisant — le serveur d'API, MariaDB, Redis et Traefik — qui fait pleinement fonctionner Auth, Databases, Storage, Realtime et la Console. Les Functions serverless, les webhooks sortants et l'envoi d'e-mails en arrière-plan nécessitent les conteneurs worker et executor supplémentaires et ne sont pas activés ici. Lorsque votre projet en aura besoin, passez à la stack docker-compose officielle complète d'Appwrite et prévoyez au moins 4 Go de RAM. Pour les sauvegardes, planifiez des snapshots des volumes Docker appwrite-mariadb (données) et appwrite-uploads (fichiers).