Railway

Deploy Excalidraw

Miro Alternative. Open-source whiteboard with real-time collaboration

Deploy Excalidraw

Just deployed

/var/lib/postgresql/data

Excalidraw logo

Deploy and Host Excalidraw on Railway

Excalidraw is an open-source virtual whiteboard for sketching diagrams that look hand-drawn. Engineers use it for architecture sketches, product teams for user flows, teachers for live explanations — anything faster to draw than to describe. The style keeps a diagram looking like a draft, so people keep editing it. The hosted excalidraw.com is free but stores your scenes on infrastructure you do not control, which is why teams self-host Excalidraw on their own domain.

Deploy Excalidraw on Railway and you get the whole product, not just the drawing canvas. This template runs four services: the Excalidraw frontend, a storage backend holding shared scenes, rooms and uploaded images, a Socket.IO collaboration server relaying live edits, and a PostgreSQL database behind the storage backend. Everything sent to storage is encrypted in the browser first, and the key lives only in the URL fragment after #, which browsers never transmit — so your server holds ciphertext it cannot read. Nothing reaches Excalidraw's cloud, Firebase or third-party analytics.

Excalidraw Railway architecture

Getting Started with Excalidraw on Railway

Open the frontend service's public URL and the canvas is ready — no sign-up, no admin account and no first-run wizard, because Excalidraw has no user accounts. Pick a shape or press r, d or o, drag on the canvas, then double-click a shape to type a label inside it. Work is saved in your browser as you draw, so a reload brings it back. To check the server side, click Share and choose Export to Link: that uploads the encrypted scene to storage and returns a #json=… link you can open in another browser. Then click Share → Start session and open the room link in a second tab or another device — the other cursor should move in real time, with a participant count on the green Share button. Rooms are saved to storage too, so everyone can leave and the scene is still there when someone rejoins the link. Use Menu → Export image for a PNG or SVG to drop into a document.

Excalidraw canvas holding a hand-drawn Draft to Ship flowchart Excalidraw live collaboration session with a second cursor on canvas Excalidraw export dialog previewing the flowchart as PNG or SVG

About Hosting Excalidraw

Excalidraw's frontend is a static single-page app, which is why many self-hosted installs stop at "the canvas works but sharing doesn't". Anything leaving your browser — a share link, a room, an image pasted into a shared scene — needs somewhere to go, and the public build points at Excalidraw's hosted services. This template replaces all of them with services in your own project.

Key features:

  • Hand-drawn shapes, arrows, freedraw, text, images and embedded links
  • Real-time collaboration with live cursors and a participant list
  • End-to-end encryption for scenes and rooms; the key stays in the URL fragment
  • Export to PNG, SVG or a .excalidraw file, plus a shareable read-only link

How they fit together: the frontend is configured at container start, so storage and collaboration URLs are environment variables rather than values baked into a build. The storage backend exposes an HTTP API under /api/v2 for scenes, rooms and files, writing each encrypted blob to PostgreSQL. The collaboration server speaks Socket.IO and relays drawing operations between clients in a room; it holds no state and never sees a key.

Why Deploy Excalidraw on Railway

Railway removes the parts of this stack that are annoying to run yourself:

  • All four services deploy together, already wired to each other
  • HTTPS is provisioned automatically, which Excalidraw's browser crypto requires
  • Managed PostgreSQL instead of a database container you babysit
  • Private networking between the storage backend and its database
  • Health checks, restarts and logs per service
  • Custom domains for a permanent whiteboard URL

Common Use Cases

  • Private architecture reviews, with diagrams on infrastructure you control
  • Remote pairing and interviews — send a room link and sketch together
  • Classroom teaching, where students join by link with nothing to install
  • Diagrams for docs and pull requests, exported as SVG or PNG from the canvas

Dependencies for Excalidraw

  • alswl/excalidraw:latest — the frontend, from the self-hosting fork at github.com/alswl/excalidraw, whose image resolves configuration at container start
  • ghcr.io/kitsteam/excalidraw-storage-backend:latest — scene, room and file storage over PostgreSQL (source)
  • ghcr.io/kitsteam/excalidraw-room:latest — the Socket.IO collaboration server (source)
  • Railway PostgreSQL — durable storage for every encrypted blob

Environment Variables Reference

VariableServiceWhat it does
VITE_APP_STORAGE_BACKENDfrontendSet to http so scenes go to your storage service, not Firebase
VITE_APP_WS_SERVER_URLfrontendPublic URL of the collaboration server
VITE_APP_FIREBASE_CONFIGfrontendLeft as {} so no Firebase connection is attempted
STORAGE_URIstoragePostgreSQL connection string
STORAGE_TTLstorageHow long a scene, room or file is kept, in milliseconds
CORS_ORIGINroomOrigin allowed to open collaboration sockets

Deployment Dependencies

Hardware Requirements for Self-Hosting Excalidraw

ResourceMinimumRecommended
CPU0.5 vCPU total1–2 vCPU across the services
RAM512 MB total1–2 GB across the services
Storage1 GB PostgreSQL5 GB+ if scenes carry images
Runtimenginx, Node.js 24, PostgreSQL 18Same

Self-Hosting Excalidraw with Docker

The plain upstream image gives the canvas with sharing still pointed at Excalidraw's hosted services:

docker run -d --name excalidraw -p 3000:80 excalidraw/excalidraw:latest

A self-contained stack needs the runtime-configurable frontend plus the two backing services. The following is a minimal Docker Compose file:

services:
  frontend:
    image: alswl/excalidraw:latest
    ports: ["3000:80"]
    environment:
      VITE_APP_STORAGE_BACKEND: http
      VITE_APP_HTTP_STORAGE_BACKEND_URL: http://localhost:8080/api/v2
      VITE_APP_BACKEND_V2_GET_URL: http://localhost:8080/api/v2/scenes/
      VITE_APP_BACKEND_V2_POST_URL: http://localhost:8080/api/v2/scenes/
      VITE_APP_WS_SERVER_URL: http://localhost:8090
  storage:
    image: ghcr.io/kitsteam/excalidraw-storage-backend:latest
    ports: ["8080:8080"]
    environment:
      STORAGE_URI: postgresql://postgres:postgres@db:5432/postgres
  room:
    image: ghcr.io/kitsteam/excalidraw-room:latest
    ports: ["8090:8090"]
  db:
    image: postgres:18
    environment:
      POSTGRES_PASSWORD: postgres

Live collaboration needs crypto.subtle, exposed only over HTTPS or on localhost — a plain HTTP address on your LAN loads the canvas but cannot start a session.

How Much Does Excalidraw Cost to Self-Host?

Excalidraw is MIT-licensed and free, including the collaboration server and editor package. Excalidraw+ is the paid hosted product with accounts and team permissions; none of it is required here. Self-hosting costs only infrastructure, and this stack is small — three light containers plus a managed database.

FAQ

What is Excalidraw? An open-source whiteboard for hand-drawn-style diagrams. It runs in the browser, supports real-time collaboration, and exports to PNG, SVG or its own .excalidraw format.

What does this Railway template deploy? Four services: the Excalidraw frontend, a storage backend for scenes, rooms and images, a Socket.IO collaboration server, and PostgreSQL — pre-wired, so share links and live collaboration work as soon as the deployment is up.

Why does self-hosted Excalidraw need a database and a separate storage service? The public build sends share links to Excalidraw's servers and keeps rooms in their Firebase project. The storage service replaces both, and PostgreSQL is where those encrypted blobs live so a room survives everyone closing their tab.

How do I add password protection to a self-hosted Excalidraw? It has no accounts or login — access is by link, and scenes are encrypted with a key that travels only in the URL fragment. To close the instance itself, put an authenticating proxy in front of the three web services.

How long are shared scenes kept? The storage service expires entries after STORAGE_TTL milliseconds. This template sets roughly ten years, so nothing disappears on its own; lower it if you want links to age out.

Can I scale the collaboration server to more than one replica? Keep it at one. It relays room traffic in memory with no shared adapter, so two replicas would split a room and people on different instances would stop seeing each other's edits. The frontend and storage scale normally.


Template Content

More templates in this category

View Template
Rocky Linux
[Jul'26] Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀

codestorm
40
View Template
Foundry Virtual Tabletop
A Self-Hosted & Modern Roleplaying Platform

Lucas
71
View Template
Letta Code Remote
Run a Letta Code agent 24/7. No inbound ports, just deploy.

Letta
51