Deploy Excalidraw with the excalidraw-whiteboard template
Deploy Excalidraw with the excalidraw-whiteboard template
Stand up Excalidraw, an open-source collaborative whiteboard, on a single Quake AI instance using the validated OpenTofu template excalidraw-whiteboard. You apply the template, point two subdomains at the host and serve both over HTTPS through Caddy, set the collaboration server's domain and start the containers, open the app, start a live collaboration session, and confirm real-time sync from a second browser session.
Excalidraw keeps your team's diagrams on infrastructure you own. You run it yourself; this is a self-hosted tool you operate, not a managed multi-tenant service.
Monthly cost estimate
Pricing calculator ↗Sized as a custom package on shared vCPU.
Monthly total for the required template above. Use the configurator below to add optional pieces and see the total update.
What each resource is for
Excalidraw whiteboard host
s1a.small · 2 shared vCPU, 2 GiB RAM, 0.5 Gbps
Runs the Excalidraw frontend and the excalidraw-room collaboration server as two stateless containers on the same instance, with no bundled datastore.
Both containers are lightweight and stateless, so 2 vCPU and 2 GiB RAM covers a small team; the lightest ops-tools footprint in this library alongside Uptime Kuma.
Compute shown per role at custom-package rates ($29/dedicated vCPU, $7.25/shared vCPU, $1/GiB RAM). The headline above is the billed total: the cheaper of a named plan and the custom package, plus add-ons.
Included in baseline
s1a.small
2 shared vCPU, 2 GiB RAM, 0.5 Gbps
Compute + RAM rate basis
2 vCPU + 2 GiB RAM at $29/dedicated vCPU, $7.25/shared vCPU, $1/GiB RAM (regular). Totals apply the flat −$5/mo package promotion.
Block storage (20 GiB)
20 GiB at $0.08/GiB/mo
Public IP (included)
1 included with the custom package
Package promotional discount
Flat −$5.00/mo on the custom package (same promotion as named plans).
Included at no charge
These line items are zero on Quake AI. Many other providers meter them separately.
Data transfer (inbound and outbound)
Unlimited data transfer on every plan; Quake AI does not meter per-GB egress.
AWS, GCP, and Azure meter outbound transfer per GB. DigitalOcean and Hetzner include an allowance on compute plans, then charge overage.
Learn morePrivate networking
Private networks, subnets, Neutron routers, and security groups are included with the plan.
VPC objects are usually free to create elsewhere, but NAT gateways bill hourly plus per-GB processed. Quake AI uses router SNAT with no separate NAT line item.
Control-plane API requests
OpenStack API calls for provisioning and management are included.
Some managed services on other clouds meter API calls or charge for premium control-plane features.
Pricing data last validated: . For current rates, check quake.ai/pricing.
Prerequisites#
You need:
- OpenTofu 1.6.0 or later (or Terraform 1.6.0 or later) installed locally.
- Your OpenStack credentials sourced into the shell (
source openrc.sh). See the OpenStack CLI guide. - An SSH keypair that already exists in your project. Record its name for the
key_namevariable. - A copy of the
excalidraw-whiteboardtemplate directory from the template reference page. - Two subdomains you can point at the instance.
Step 1: Apply the template#
Copy the template's example variables file and set key_name:
cp terraform.tfvars.example terraform.tfvarskey_name = "YOUR_KEY_NAME"Initialize, preview, and apply:
tofu init
tofu plan
tofu applyOpenTofu provisions a private network, a router, a security group, an instance, and a floating IP. On first boot, cloud-init installs Docker Engine and writes /opt/excalidraw/docker-compose.yml and /opt/excalidraw/.env, but does not start either container: the frontend's collaboration-URL patch depends on knowing the real public domain first.
Read the outputs and record floating_ip:
tofu outputStep 2: Point two domains at the host and serve HTTPS with Caddy#
- Create two DNS A records, for example
draw.example.comandcollab.example.com, both pointing atYOUR_FLOATING_IP. Follow How to point a domain at a Quake AI resource. Wait until both resolve:
dig +short draw.example.com
dig +short collab.example.com- SSH to the instance and create
/opt/excalidraw/Caddyfile:
draw.example.com {
reverse_proxy 127.0.0.1:8080
}
collab.example.com {
reverse_proxy 127.0.0.1:8081
}Caddy upgrades WebSocket connections automatically inside reverse_proxy, so the collaboration block needs no extra configuration.
- Add Caddy to
/opt/excalidraw/docker-compose.yml:
services:
caddy:
image: caddy:2
restart: unless-stopped
network_mode: host
volumes:
- /opt/excalidraw/Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
volumes:
caddy_data:For background on certificates, see How to issue and auto-renew a TLS certificate with Let's Encrypt.
Step 3: Set the collaboration domain and start Excalidraw#
Edit /opt/excalidraw/.env and set:
VITE_APP_WS_SERVER_URL=https://collab.example.comStart the full stack:
cd /opt/excalidraw
sudo docker compose up -dCheck the frontend container's logs for the patch confirmation:
docker compose logs excalidraw | grep "Patching hardcoded collab URL"Step 4: Start a live collaboration session#
- Open
https://draw.example.com. - Open the hamburger menu in the top left and select Live collaboration.
- Select Start session and copy the generated share link.
Step 5: Confirm real-time sync from a second browser session#
- Open the share link in a second browser or an incognito window.
- Draw a shape in one window and confirm it appears in the other within a second or two.
- Open the browser's developer tools, filter the network tab to
WS, and confirm the open WebSocket connects tocollab.example.com, notoss-collab.excalidraw.com. That confirms the collaboration-URL patch applied correctly.
What you built#
- Applied the
excalidraw-whiteboardtemplate to provision a network, security group, instance, and floating IP, with both containers held until configuration finished - Served two hostnames over HTTPS by pointing both domains at the floating IP and routing them through a Caddy reverse proxy, with WebSocket upgrade on the collaboration hostname
- Set the collaboration domain and started both containers
- Started a live collaboration session and confirmed real-time sync between two browser sessions
Scope of this deployment#
This template runs a single-VM Excalidraw host, not a managed multi-tenant whiteboard service. The instance is CPU-only and runs in one region, and it bundles no database because there is nothing to persist server-side: drawing content lives in each browser's local storage, and the collaboration server relays end-to-end-encrypted data without persisting it. You operate the instance, Docker, and both containers yourself. The collaboration server has no built-in authentication, so anyone with a live share link can join a room; this suits a small trusted team rather than a public-facing deployment.
Next steps#
- Excalidraw whiteboard template: the template reference, parameters, and resource map
- Nextcloud files and collaboration template: another ops-tools template with a similar domain-first setup pattern
- Security hardening checklist: tighten SSH access and exposure before you connect production traffic
Clean up#
When you no longer need the deployment, destroy everything the template created:
tofu destroyThen remove the two DNS A records you created in step 2.
See Also
Instances
Prerequisite
Migrate a Docker container app from AWS to Quake AI
Shares: Docker, Containers
Deploy Airbyte with the airbyte template
Shares: Docker, Containers
Deploy Airflow with the airflow template
Shares: Docker, Containers
Deploy Umami with the analytics-umami template
Shares: Docker, Containers