How do I deploy Excalidraw locally using Docker and a reverse proxy?
Executive summary
Deploying the Excalidraw client locally is straightforward: pull the official Docker image and run it, or use docker-compose for a fuller stack; exposing it securely to the internet requires a reverse proxy that supports WebSocket proxying and TLS termination such as Nginx or Traefik [1] [2] [3]. For real-time collaboration or storage backends, additional services (collab server, Redis or storage backends) and environment variable wiring are required, and the community guides emphasize careful reverse-proxy configuration for WebSocket support and domain-specific URLs [4] [5] [6].
1. Minimal local deployment: official Docker image and quick run
The fastest path is to pull the official client image and run it as a single container: docker pull excalidraw/excalidraw and docker run --rm -dit --name excalidraw -p 5000:80 excalidraw/excalidraw:latest, which maps the container’s port 80 to a host port so the editor is reachable in a browser [2] [1]. This client is stateless and stores drawing data in the browser by default, which explains why many quick-start guides don’t configure persistent storage [2] [7].
2. When to move beyond a single container: collaboration and storage
If collaboration or shared canvases are required, the Excalidraw project and community examples advise deploying a collab server and optional storage backend; the developer docs recommend spinning up a collab server locally for collaboration and note docker-compose as an alternative to a Node.js dev environment [4]. Community full-stack tutorials add Redis as a temporary store used by storage backends and warn it cannot guarantee persistent reliability unless configured appropriately [5].
3. Using docker-compose for a manageably reproducible stack
Several how‑tos provide docker‑compose recipes that define excalidraw as a service, often binding it to 127.0.0.1:5000 or another internal port and leaving TLS to the reverse proxy layer; docker compose up -d is the usual command to start the stack [8] [7]. Forks and community repos that bundle collaboration and storage services instruct operators to replace VITE_APP_HTTP_STORAGE_BACKEND_URL and VITE_APP_WS_SERVER_URL with the public domain names for production exposure [6].
4. Reverse proxy essentials: WebSockets, headers, and TLS termination
Reverse proxies must forward WebSocket upgrades and preserve host and proto headers; sample Nginx configs include proxy_http_version 1.1 and proxy_set_header lines for Upgrade, Connection, Host, X-Real-IP, X-Forwarded-For and X-Forwarded-Proto to ensure real-time collaboration works over HTTPS [9]. Guides repeatedly advise binding the Docker service to localhost and letting Nginx or Traefik handle public TLS and routing — Traefik is mentioned as an easy way to add HTTPS for home lab setups [3] [7]. The Synology and other platform docs explicitly warn that enabling WebSocket support is mandatory to run Excalidraw via HTTPS [10].
5. Security, production polish, and common operational notes
Production guides recommend restricting exposed ports to 80/443, using Let’s Encrypt for certificates, enabling firewall rules, adding basic rate limiting, and protecting internal endpoints if publicly reachable; platform-specific guides add SELinux or UFW steps for their distributions [9] [11] [12]. Community deployments also emphasize internal Docker networking for backend services and suggest keeping persistent secrets and proper certificate management inside the proxy layer [13].
6. Tradeoffs, alternatives, and hidden agendas in the guides
The tradeoff is clear: a single container is fast and stateless, good for private, simple use, while full collaboration requires extra services, config, and testing [2] [4] [5]. Several “how-to” articles come from hosting providers that promote their VPS offerings as part of the narrative, which represents a commercial angle rather than a technical necessity [7] [11] [12]. Community discussion threads show challenges when consolidating multiple services under one domain, so expect extra DNS or proxy work if aiming for a single hostname for client and collab endpoints [14].