Tutoriel

Héberger Excalidraw sur VPS : tableau blanc sans abonnement

Self-hosting8 min de lecture5 étapes

Miro, FigJam, Lucidspark : les tableaux blancs SaaS facturent au siège, stockent vos maquettes sur leurs serveurs et plafonnent les membres par plan. Excalidraw est l'alternative open source (MIT) : un tableau blanc dessiné à la main, collaboratif en temps réel, dont les deux composants — l'interface React et le serveur de salle WebSocket — s'auto-hébergent sur un VPS en deux conteneurs Docker. Ce guide montre comment les déployer, câbler nginx pour les WebSockets et activer la persistance des tableaux.

Sommaire· Pourquoi auto-héberger Excalidraw plutôt que d'utiliser la version en ligne1/10
  1. 01Pourquoi auto-héberger Excalidraw plutôt que d'utiliser la version en ligne
  2. 02Ce que vous gagnez concrètement
  3. 03Architecture : deux conteneurs, rôles distincts
  4. 04Prérequis
  5. 05Checklist prérequis
  6. 06Déployer Excalidraw en 5 étapes
  7. 07Persistance des tableaux : deux approches
  8. 08Excalidraw auto-hébergé vs alternatives SaaS
  9. 09Aller plus loin : SSO et allowlist d'IP
  10. 10Intégration dans un parc self-hosted

Pourquoi auto-héberger Excalidraw plutôt que d'utiliser la version en ligne

La version publique sur excalidraw.com fonctionne bien pour un dessin rapide en solo. Elle envoie les sessions de collaboration en temps réel vers un serveur géré par Excalidraw s.r.o. C'est acceptable pour un brainstorming ponctuel. Ce l'est beaucoup moins quand les tableaux contiennent des maquettes de flux clients, des schémas d'architecture de systèmes internes ou des wireframes de projets sous NDA.

Auto-héberger Excalidraw déplace le périmètre de contrôle sur votre propre infrastructure. Vos sessions passent par votre serveur WebSocket, sur votre domaine, sans transiter par un tiers. Vous décidez qui se connecte — par allowlist d'IP, par SSO OIDC ou par HTTP Basic Auth devant nginx. Et comme les deux composants sont publiés sous licence MIT, aucune restriction commerciale ne s'applique quel que soit le nombre de clients ou de collaborateurs que vous faites travailler sur l'instance.

Ce que vous gagnez concrètement

  • Zéro abonnement logiciel — les deux composants (interface et serveur de collaboration) sont MIT. Vous payez le VPS, rien d'autre.
  • Confidentialité des maquettes — les sessions de dessin restent sur votre infrastructure. Aucun fichier de conception ne transite par un tiers.
  • Accès sous votre contrôle — allowlist d'IP, SSO OIDC ou HTTP Basic Auth devant nginx selon le niveau d'isolation requis.
  • Sessions et membres sans quota imposés — pas de plafond par plan ; la seule limite est la RAM du serveur, et excalidraw-room est un service Node.js léger.
  • Persistance optionnelle — montez un volume Docker ou branchez un bucket S3 compatible pour archiver les tableaux exportés en JSON.
  • Intégration dans un parc self-hosted — une instance Excalidraw aux côtés de Penpot, Mattermost ou Docmost ferme le périmètre SaaS de toute une agence.

Architecture : deux conteneurs, rôles distincts

Excalidraw sépare ce que la plupart des gens considèrent comme un seul outil en deux composants indépendants :

- excalidraw/excalidraw — l'interface React compilée, servie comme un site statique par nginx à l'intérieur du conteneur. Elle ne fait tourner aucun serveur applicatif. Sa seule contrainte est la variable VITE_APP_WS_SERVER_URL, qui doit pointer vers votre serveur de salle au moment de la compilation de l'image. Cette variable est gravée dans le bundle JavaScript : si vous la changez sur un conteneur déjà lancé, rien ne bouge.

- excalidraw/excalidraw-room — un serveur Node.js Socket.IO qui relaie en mémoire les événements de dessin entre les participants d'une même session. Il est stateless : il ne persiste rien et oublie tout au redémarrage. Les dessins vivent dans le localStorage du navigateur ou sont exportés manuellement.

Conséquence pratique : l'image Docker officielle pointe en dur sur le serveur de collaboration d'Excalidraw. Pour rediriger vers votre propre excalidraw-room, vous devez builder votre propre image avec VITE_APP_WS_SERVER_URL positionné sur votre domaine — ou utiliser un entrypoint qui patche le bundle au démarrage.

Prérequis

Le VPS Start de ServOrbit (2 vCPU, 4 GB RAM) couvre le cas nominal : l'interface statique est quasi sans charge, et excalidraw-room consomme moins de 256 Mo en régime courant. Avec une dizaine de collaborateurs simultanés, vous resterez largement sous la moitié de la RAM disponible.

Ce qu'il vous faut avant de commencer :

Checklist prérequis

  • Un VPS avec au moins 1 vCPU et 512 Mo de RAM (1 Go recommandé pour une équipe).
  • Docker Engine et Docker Compose Plugin installés (docker compose version pour vérifier).
  • Un nom de domaine pointé vers l'IP du VPS — sans TLS les WebSockets sont bloqués par les navigateurs modernes.
  • Accès SSH root ou un utilisateur avec droits sudo.
  • Un certificat TLS valide — ServOrbit configure Let's Encrypt automatiquement.

Déployer Excalidraw en 5 étapes

  1. Créer le VPS et installer Docker

    Provisionnez un VPS Ubuntu 24.04 depuis l'espace ServOrbit. Une fois connecté en SSH, si Docker n'est pas encore présent, installez-le en une passe :

    curl -fsSL https://get.docker.com | sh

    Vérifiez que Docker Compose Plugin répond avant de continuer :

    docker compose version
  2. Builder l'image avec votre URL de collaboration

    Clonez le dépôt officiel, puis construisez l'image en substituant votre domaine. Remplacez collab.yourdomain.com par le sous-domaine que vous allouez à excalidraw-room :

    git clone https://github.com/excalidraw/excalidraw.git
    cd excalidraw
    docker build \
      --build-arg VITE_APP_WS_SERVER_URL=wss://collab.yourdomain.com \
      -t my-excalidraw:latest .

    Cette étape grave l'URL du serveur WebSocket dans le bundle JavaScript. Si vous changez de domaine plus tard, il faudra rebuilder. L'image officielle excalidraw/excalidraw convient pour les tests locaux, mais elle pointe sur le serveur public d'Excalidraw — inutilisable pour un déploiement souverain.

  3. Écrire le fichier docker-compose.yml

    Créez un répertoire de travail et posez le fichier suivant. Les deux services écoutent en interne ; nginx (à l'étape suivante) est le seul point d'entrée public :

    mkdir ~/excalidraw-stack && cd ~/excalidraw-stack

    Contenu du docker-compose.yml :

    services:
      excalidraw:
        image: my-excalidraw:latest
        restart: unless-stopped
        networks:
          - excalidraw
    
      excalidraw-room:
        image: excalidraw/excalidraw-room:latest
        restart: unless-stopped
        networks:
          - excalidraw
    
    networks:
      excalidraw:

    Lancez la stack :

    docker compose up -d
  4. Configurer nginx avec les en-têtes WebSocket

    C'est l'étape où la plupart des déploiements échouent en silence : sans les en-têtes Upgrade et Connection, le navigateur ouvre une connexion HTTP normale au lieu d'un WebSocket, et la collaboration semble ne pas démarrer sans aucun message d'erreur visible.

    Bloc nginx pour le frontend Excalidraw (draw.yourdomain.com) :

    server {
        listen 443 ssl;
        server_name draw.yourdomain.com;
    
        location / {
            proxy_pass http://excalidraw:80;
            proxy_set_header Host $host;
        }
    }

    Bloc nginx pour le serveur de salle (collab.yourdomain.com) :

    server {
        listen 443 ssl;
        server_name collab.yourdomain.com;
    
        location / {
            proxy_pass http://excalidraw-room:80;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header Host $host;
            proxy_read_timeout 86400s;
        }
    }

    Rechargez nginx (nginx -s reload) après avoir posé les blocs.

  5. Tester la collaboration en temps réel

    Ouvrez https://draw.yourdomain.com dans deux onglets ou deux navigateurs différents. Dans la barre d'outils, cliquez sur Live collaboration et créez une session. Copiez le lien de session dans le second onglet.

    Dessinez quelque chose dans le premier onglet : le trait doit apparaître dans le second en temps réel. S'il n'apparaît pas, vérifiez d'abord les en-têtes WebSocket dans nginx (les devtools réseau du navigateur montrent si la connexion est passée en 101 Switching Protocols). Un status 200 sur la requête WebSocket indique que nginx n'a pas transmis les en-têtes Upgrade.

Persistance des tableaux : deux approches

Par défaut, excalidraw-room est entièrement stateless. Si le serveur redémarre, la session en cours est perdue — mais chaque participant conserve localement ce qu'il a dessiné dans son localStorage.

Option 1 — Export JSON automatique. Configurez un cron ou un script qui appelle l'API d'export d'Excalidraw et enregistre les fichiers .excalidraw dans un volume Docker. Ces fichiers peuvent être réimportés à tout moment depuis l'interface.

Option 2 — Bucket S3 compatible. ServOrbit propose un stockage objet S3 compatible. Branchez votre bucket comme destination d'archivage des exports ; la restauration en cas de panne se fait par réimport du dernier fichier sauvegardé.

Excalidraw auto-hébergé vs alternatives SaaS

Faites défiler le tableau

CritèreExcalidraw (self-hosted)MiroFigJam
Coût par utilisateurAucun (VPS seul)Payant par siègePayant par siège
Données hébergées chezVotre infrastructureMiro Inc.Adobe / Figma
Membres simultanésRAM seuleLimité par planLimité par plan
Licence logicielleMIT (open source)PropriétairePropriétaire
Auto-hébergeableOui, deux conteneursNonNon
Contrôle d'accèsIP / SSO / Basic AuthSSO (plans Pro)SSO (plans Edu+)

Aller plus loin : SSO et allowlist d'IP

Pour une agence dont les clients ont des exigences de confidentialité strictes, exposer Excalidraw sur un sous-domaine public n'est pas toujours acceptable. Deux configurations courantes permettent de durcir l'accès sans modifier Excalidraw lui-même.

HTTP Basic Auth via nginx. Ajoutez une directive auth_basic devant le bloc location / du frontend. Toute personne qui tente d'ouvrir l'interface devra s'authentifier avant même que l'app React se charge. Simple à mettre en place, suffisant pour des projets internes.

Allowlist d'IP. Si les collaborateurs se connectent depuis des IP fixes ou depuis un VPN d'entreprise, un bloc allow/deny dans nginx suffit à fermer l'instance au reste d'Internet :

allow 203.0.113.0/24;
allow 198.51.100.42;
deny all;

SSO OIDC via un reverse proxy authentifiant. Pour les équipes qui disposent déjà d'un fournisseur d'identité (Keycloak, Authelia, Authentik), un proxy authentifiant comme Oauth2-Proxy ou Authelia posé devant nginx délègue l'authentification au SSO existant. Excalidraw n'a pas besoin de savoir qu'une couche d'auth supplémentaire existe.

Intégration dans un parc self-hosted

Excalidraw s'intègre naturellement dans un parc d'outils auto-hébergés. Si vous avez déjà déployé Mattermost pour la communication d'équipe, vous pouvez coller un lien de session Excalidraw dans un canal et inviter vos collaborateurs à rejoindre le tableau directement. Si Penpot couvre le design haute fidélité, Excalidraw prend en charge le travail en amont — les wireframes rapides, les schémas de flux et les sessions de brainstorming — avant que les designs n'entrent dans Penpot.

Cette complémentarité est le vrai argument face aux SaaS : chaque outil reste dans son périmètre de compétences, sans forfait plateforme qui facture pour des fonctions dont vous n'avez pas besoin.

Une plateforme pour votre VPS, votre domaine et vos sauvegardes

ServOrbit centralise VPS, nom de domaine et sauvegardes dans un espace agence unique : déployez Excalidraw pour votre équipe et gérez l'infrastructure de vos clients depuis le même tableau de bord.

Besoin d'aide ?

Parcourez notre centre d'aide et notre FAQ, ou contactez notre équipe — rappel, WhatsApp ou e-mail. Support en français, anglais et arabe.

Écrire sur WhatsApps'ouvre dans un nouvel onglet