Self-Host Excalidraw: Private Real-Time Whiteboarding

cover

Overview

Excalidraw is an open-source virtual whiteboard focused on low-latency collaboration, infinite canvases, and whimsical hand-drawn visuals. Running your own Excalidraw instance keeps brainstorming artifacts, architecture diagrams, and workshops inside your network while preserving the frictionless UX designers and engineers expect.

Why Self-Host Excalidraw?

  • Data Residency – Keep retros, OKR planning boards, and customer notes within your own storage buckets or Git repos.
  • Air-Gapped Readiness – Deliver collaborative sketching to teams that cannot reach the public SaaS due to compliance or NDAs.
  • Customization – Extend with custom libraries, default templates, or embed the canvas into internal tools without external calls.
  • Vendor Independence – Control release cadence, apply hotfixes faster, and integrate with your auth provider instead of relying on invite links.

Feature Highlights

✏️ Fast, Friendly Canvas

  • Infinite canvas with snapping, grouping, and z-index tools.
  • Hand-drawn look produces approachable diagrams for ideation sessions.
  • Built-in shape library (arrows, connectors, UML, sticky notes) plus import/export of .excalidrawlib libraries.

🤝 Real-Time Collaboration

  • Peer-to-peer synchronization via WebRTC + WebSocket transport with conflict-free replicated data (CRDT) data model.
  • Presence indicators, live cursors, and follow mode keep workshops cohesive.
  • Export snapshots to PNG/SVG/PDF with transparent backgrounds for slide decks or docs.

🧩 Extensible Platform

  • Embed Excalidraw into React, Next.js, or custom portals via the @excalidraw/excalidraw component.
  • Build plugins that sync to Notion, Confluence, or markdown repos through the Scene API.
  • Wire up automation (e.g., pushing diagrams to GitHub on save) by subscribing to the onChange callback.

Deployment Options

version: '3.8'
services:
  excalidraw:
    image: ghcr.io/excalidraw/excalidraw:latest
    container_name: excalidraw
    restart: unless-stopped
    environment:
      - NODE_ENV=production
      - VITE_APP_BACKEND_V2_GET_URL=https://excalidraw.example.com
      - VITE_APP_FIREBASE_CONFIG={}
      - STORAGE_URI=file-system
    ports:
      - '3001:80'
    volumes:
      - ./data:/app/web/public/data

  peer-server:
    image: ghcr.io/excalidraw/excalidraw-room:latest
    restart: unless-stopped
    environment:
      - PORT=8080
      - REDIS_URI=redis://redis:6379
    depends_on:
      - redis
    ports:
      - '8080:8080'

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    volumes:
      - redis-data:/data

volumes:
  redis-data:
  1. Update VITE_APP_BACKEND_V2_GET_URL to the public hostname that fronts the peer server.
  2. Run docker compose up -d.
  3. Place custom libraries or default scenes in ./data.

Static Hosting + Room Server

  1. Clone https://github.com/excalidraw/excalidraw.
  2. pnpm install && pnpm build:app.
  3. Serve packages/excalidraw/dist with any static host (Nginx, Netlify, Vercel, S3 + CloudFront).
  4. Deploy the @excalidraw/room server (Node.js) behind HTTPS or WebSocket load balancer.

This split architecture lets you host the UI on a CDN while confining real-time traffic to private infrastructure.

Kubernetes

  • Use a Deployment for the web app (static container) with a ConfigMap for environment flags.
  • Run the room server as a separate Deployment with Redis or KeyDB as backing store.
  • Expose via Ingress (Nginx/Traefik) with sticky sessions for the WebSocket service.
  • Mount PersistentVolume for scene backups or custom libraries shared among pods.

Storage & Sync Options

Use CaseStrategy
Persistent boards per teamMount shared volume and enable STORAGE_URI=file-system or plug in Excalidraw+ storage adapters.
Docs-as-CodeRun a bot that exports .excalidraw files to Git after every workshop.
External backupMirror ./data to S3/MinIO nightly; files are portable JSON scenes.

Authentication & Security

  • Terminate TLS at a reverse proxy (Caddy, Nginx) and enforce HTTPS redirects.
  • Protect the UI behind SSO (Authelia, Authentik, Keycloak) using forward auth headers.
  • Restrict WebSocket origins so only your UI endpoint can talk to the room server.
  • Enable rate limiting on /socket.io/ endpoints to avoid abuse during public demos.

Customization Ideas

  • Preload templates (journey maps, architecture review) by shipping .excalidraw files in /public/data.
  • Add brand-specific color palettes by editing src/constants.ts before building.
  • Toggle VITE_APP_DISABLE_ANALYTICS=true to remove telemetry entirely.
  • Embed Excalidraw inside docs portals for contextual sketching next to RFCs.

Operations Checklist

  • Monitor room-server metrics (connections, socket errors, Redis memory) with Prometheus exporters.
  • Schedule dependency updates; the upstream repo frequently patches collaborative edge cases.
  • Capture daily backups of Redis if you store room history for compliance.
  • Load test WebSocket concurrency with k6 or Artillery before a large workshop.

Self-hosted Excalidraw delivers the same joyful brainstorming experience as the hosted app while keeping every pixel of ideation under your governance.

You might also like