Self-Hosting Excalidraw with Docker Compose

What Is Excalidraw?

Excalidraw is an open-source virtual whiteboard for sketching diagrams with a hand-drawn feel. It supports real-time collaboration, a massive library of community shapes, and exports to PNG, SVG, and its own .excalidraw format. The self-hosted version runs entirely in the browser — the server just delivers static files through Nginx, so there’s no database, no backend state, and almost zero resource requirements.

Prerequisites

  • A Linux server (Ubuntu 22.04+ recommended)
  • Docker and Docker Compose installed (guide)
  • 50 MB of free disk space (seriously, that’s it)
  • 256 MB of RAM (Nginx serving static files)
  • A domain name (optional, for remote access)

How Self-Hosted Excalidraw Works

Excalidraw’s architecture is unusual: the Docker container is just Nginx serving a pre-built JavaScript application. All drawing data lives in the user’s browser via localStorage and IndexedDB. The server never sees your diagrams.

FeatureSelf-Hostedexcalidraw.com
Drawing & editingFullFull
Export (PNG, SVG, .excalidraw)FullFull
Community librariesFull (fetched from CDN)Full
Link-based sharingNoYes
Real-time collaborationRequires custom buildYes
Cloud persistenceNo (browser-only)Yes (Firebase)
Analytics/trackingNoneMinimal

Self-hosting gives you a completely private whiteboard — nothing leaves the browser. The trade-off is no built-in sharing or collaboration without extra work.

Docker Compose Configuration

Create a docker-compose.yml file:

services:
  excalidraw:
    # No semver Docker tags published — only :latest and SHA-based tags available
    image: excalidraw/excalidraw:latest
    container_name: excalidraw
    restart: unless-stopped
    ports:
      - "3000:80"
    healthcheck:
      test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://localhost"]
      interval: 30s
      timeout: 10s
      retries: 3

That’s the entire configuration. No environment variables, no volumes, no database.

Start Excalidraw:

docker compose up -d

Access the whiteboard at http://your-server-ip:3000.

A note on version pinning: Excalidraw’s Docker Hub image does not publish semver tags — only latest and commit-SHA tags like sha-4bfc5bb. Use latest and document when you last pulled the image. To pin to a specific build, use the digest:

image: excalidraw/excalidraw@sha256:<digest>

Using Excalidraw

Once deployed, Excalidraw works exactly like the public version at excalidraw.com, minus cloud features:

  1. Open the URL in any modern browser
  2. Draw using the toolbar (rectangles, ellipses, arrows, text, freehand)
  3. Import community libraries via the hamburger menu → Libraries
  4. Export your work as PNG, SVG, clipboard image, or .excalidraw JSON
  5. Share drawings by exporting the .excalidraw file and sending it to others

All data persists in the browser. Clearing browser data erases your drawings — export anything you want to keep.

Adding Real-Time Collaboration

The pre-built Docker image points to Excalidraw’s hosted collaboration server (oss-collab.excalidraw.com). To self-host collaboration, you need to:

  1. Clone the Excalidraw repository
  2. Set VITE_APP_WS_SERVER_URL to your own server
  3. Build a custom Docker image
  4. Run the excalidraw-room WebSocket relay alongside it
services:
  excalidraw:
    build:
      context: ./excalidraw
      args:
        - NODE_ENV=production
    container_name: excalidraw
    restart: unless-stopped
    ports:
      - "3000:80"
    depends_on:
      - excalidraw-room

  excalidraw-room:
    # No semver Docker tags published — :latest only
    image: excalidraw/excalidraw-room:latest
    container_name: excalidraw-room
    restart: unless-stopped
    environment:
      - PORT=80
      - CORS_ORIGIN=https://draw.example.com
    ports:
      - "3002:80"

Before building, clone the repo and create .env.production:

git clone https://github.com/excalidraw/excalidraw.git
echo "VITE_APP_WS_SERVER_URL=https://draw.example.com:3002" > excalidraw/.env.production

The room server is stateless — it relays encrypted drawing data between connected clients in memory. Nothing is stored server-side.

Reverse Proxy

Since Excalidraw is a simple static site, any reverse proxy works. For Nginx Proxy Manager, point to http://excalidraw:80 (or the host port 3000). If using the collaboration server, add a second proxy host for the room server with WebSocket support enabled.

For a dedicated reverse proxy setup, see Reverse Proxy Guide.

Backup

There’s nothing to back up on the server. Excalidraw stores all data client-side. If you want to preserve drawings, export them as .excalidraw files from the browser and store those files in your backup system.

If you run the collaboration server, it’s completely stateless — no backup needed there either.

For general backup strategies, see Backup Strategy.

Troubleshooting

Blank White Page After Deploy

Symptom: Browser shows a blank page or loading spinner that never resolves.

Fix: Check browser console for CORS or mixed-content errors. If you’re behind a reverse proxy, make sure it’s passing the correct Host header and not stripping Content-Type headers for JavaScript and CSS files.

Community Libraries Won’t Load

Symptom: The Libraries panel is empty or shows an error.

Fix: Community libraries are fetched from libraries.excalidraw.com. Your server needs outbound HTTPS access. If you’re in an air-gapped environment, libraries won’t work — you’ll need to download and import them manually as .excalidrawlib files.

Symptom: Clicking “Live collaboration” creates a link, but other users can’t join.

Fix: The pre-built Docker image uses Excalidraw’s hosted collaboration server. This works but means collaboration traffic routes through their servers. For fully self-hosted collaboration, follow the custom build steps above.

Resource Requirements

  • RAM: ~20-30 MB idle (Nginx only)
  • CPU: Negligible (static file serving)
  • Disk: ~50 MB for the Docker image
  • Network: Initial page load is ~5-10 MB, then everything runs client-side

Excalidraw is one of the lightest self-hosted applications you can run. A Raspberry Pi handles it without breaking a sweat.

Verdict

Excalidraw is the best self-hosted whiteboard for quick diagrams and sketches. The hand-drawn aesthetic makes technical diagrams and architecture sketches look approachable rather than corporate. The zero-server-state architecture is both a strength (trivial to deploy, nothing to back up, completely private) and a limitation (no built-in persistence or sharing without extra work).

If you need persistent server-side storage or built-in collaboration without a custom build, look at Penpot instead. But for a drop-in private whiteboard that just works, Excalidraw is hard to beat.

Comments