---
title: "Deploy Excalidraw"
description: "Miro Alternative. Open-source whiteboard with real-time collaboration"
category: "Other"
url: https://railway.com/deploy/excalidraw-whiteboard
---

# Deploy Excalidraw

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

**[Deploy Excalidraw on Railway](https://railway.com/template/excalidraw-whiteboard)**

- **Creator:** A3A
- **Category:** Other
- **Total deploys:** 1

## Template content

### storage https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/excalidraw.svg

- **Image:** ghcr.io/kitsteam/excalidraw-storage-backend:latest
- **Health check:** /api/v2/health
- **Public domain:** Yes

### excalidraw https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/excalidraw.svg

- **Image:** alswl/excalidraw:latest
- **Health check:** /
- **Public domain:** Yes

### room https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/excalidraw.svg

- **Image:** ghcr.io/kitsteam/excalidraw-room:latest
- **Health check:** /
- **Public domain:** Yes

### Postgres https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/postgresql.svg

- **Image:** ghcr.io/railwayapp-templates/postgres-ssl:18

## Documentation

![Excalidraw logo](https://res.cloudinary.com/rroe4rtk/image/upload/v1787183488/163a3d24-9e2d-4802-a800-8c3a0632b824.png)

# 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](https://res.cloudinary.com/rroe4rtk/image/upload/v1787183464/aaa41a7d-41fc-4860-bf9f-763cd23e8abb.png)

## 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](https://res.cloudinary.com/rroe4rtk/image/upload/v1787079649/excalidraw-flowchart-canvas.png)
![Excalidraw live collaboration session with a second cursor on canvas](https://res.cloudinary.com/rroe4rtk/image/upload/v1787079655/excalidraw-live-collaboration.png)
![Excalidraw export dialog previewing the flowchart as PNG or SVG](https://res.cloudinary.com/rroe4rtk/image/upload/v1787079661/excalidraw-export-image.png)

## 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](https://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](https://github.com/kitsteam/excalidraw-storage-backend))
- `ghcr.io/kitsteam/excalidraw-room:latest` — the Socket.IO collaboration server ([source](https://github.com/kitsteam/excalidraw-room))
- Railway PostgreSQL — durable storage for every encrypted blob

### Environment Variables Reference

| Variable | Service | What it does |
|---|---|---|
| `VITE_APP_STORAGE_BACKEND` | frontend | Set to `http` so scenes go to your storage service, not Firebase |
| `VITE_APP_WS_SERVER_URL` | frontend | Public URL of the collaboration server |
| `VITE_APP_FIREBASE_CONFIG` | frontend | Left as `{}` so no Firebase connection is attempted |
| `STORAGE_URI` | storage | PostgreSQL connection string |
| `STORAGE_TTL` | storage | How long a scene, room or file is kept, in milliseconds |
| `CORS_ORIGIN` | room | Origin allowed to open collaboration sockets |

### Deployment Dependencies

- Upstream project: [github.com/excalidraw/excalidraw](https://github.com/excalidraw/excalidraw)
- Self-hosting stack this template follows: [github.com/alswl/excalidraw-collaboration](https://github.com/alswl/excalidraw-collaboration)
- Runtime: nginx, Node.js 24 for storage and collaboration, PostgreSQL 18

## Hardware Requirements for Self-Hosting Excalidraw

| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 0.5 vCPU total | 1–2 vCPU across the services |
| RAM | 512 MB total | 1–2 GB across the services |
| Storage | 1 GB PostgreSQL | 5 GB+ if scenes carry images |
| Runtime | nginx, Node.js 24, PostgreSQL 18 | Same |

## 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.


## Similar templates

- [Rocky Linux](https://railway.com/deploy/rocky-linux) — Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀
- [Foundry Virtual Tabletop](https://railway.com/deploy/X5tR6G) — A Self-Hosted & Modern Roleplaying Platform
- [Letta Code Remote](https://railway.com/deploy/letta-code-remote) — Run a Letta Code agent 24/7. No inbound ports, just deploy.

Open this page in a browser: https://railway.com/deploy/excalidraw-whiteboard
