Self-Host Excalidraw: Private Real-Time Whiteboarding

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
.excalidrawliblibraries.
🤝 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
onChangecallback.
Deployment Options
Docker Compose (Recommended)
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:
- Update
VITE_APP_BACKEND_V2_GET_URLto the public hostname that fronts the peer server. - Run
docker compose up -d. - Place custom libraries or default scenes in
./data.
Static Hosting + Room Server
- Clone
https://github.com/excalidraw/excalidraw. pnpm install && pnpm build:app.- Serve
packages/excalidraw/distwith any static host (Nginx, Netlify, Vercel, S3 + CloudFront). - Deploy the
@excalidraw/roomserver (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 Case | Strategy |
|---|---|
| Persistent boards per team | Mount shared volume and enable STORAGE_URI=file-system or plug in Excalidraw+ storage adapters. |
| Docs-as-Code | Run a bot that exports .excalidraw files to Git after every workshop. |
| External backup | Mirror ./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
.excalidrawfiles in/public/data. - Add brand-specific color palettes by editing
src/constants.tsbefore building. - Toggle
VITE_APP_DISABLE_ANALYTICS=trueto 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.