[{"data":1,"prerenderedAt":189},["ShallowReactive",2],{"seo-verification":3,"blog-heberger-excalidraw-vps-2-en":6},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"key":7,"data":8},"blog-heberger-excalidraw-vps-2-en",{"id":9,"slug":10,"slugs":11,"title":13,"excerpt":14,"readTime":15,"views":16,"isPinned":17,"publishedAt":18,"updatedAt":19,"category":20,"categories":26,"featuredImage":28,"bgImage":29,"posterImage":30,"relatedSolution":28,"intro":31,"sections":32,"ctaTitle":125,"ctaBody":126,"ctaButton":127,"ctaUrl":128,"relatedPosts":129},349,"heberger-excalidraw-vps-2",{"fr":12,"en":10,"ar":10,"es":10},"heberger-excalidraw-vps","Self-Hosting Excalidraw on a VPS: Open Source Whiteboard","Deploy Excalidraw on your VPS: MIT collaborative whiteboard, without quota sessions, data on your infrastructure — no Miro or FigJam subscription.",8,0,false,"2026-09-11T00:00:00+00:00","2026-09-11T11:34:13+00:00",{"id":21,"name":22,"slug":23,"color":24,"icon":25},7,"Self-hosting","self-hosting","bg-indigo-500\u002F10 text-indigo-400","cloud",[27],{"id":21,"name":22,"slug":23,"color":24,"icon":25},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Fheberger-excalidraw-vps-poster.svg","Miro, FigJam, Lucidspark: SaaS whiteboards charge per seat, store your mockups on their servers and cap members by plan. Excalidraw is the open-source alternative (MIT): a hand-drawn-style collaborative whiteboard whose two components — the React interface and the WebSocket room server — self-host on a VPS in two Docker containers. This guide shows how to deploy them, wire nginx for WebSockets and enable board persistence.",[33,37,47,50,53,61,80,84,119,122],{"type":34,"title":35,"body":36},"h2","Why self-host Excalidraw instead of using the public version","The public version at excalidraw.com works fine for quick solo sketches. It routes real-time collaboration sessions through a server managed by Excalidraw s.r.o. That is acceptable for an ad-hoc brainstorm. It is much less so when the boards contain client flow mockups, internal system architecture diagrams or wireframes covered by an NDA.\n\nSelf-hosting Excalidraw shifts the control boundary to your own infrastructure. Sessions travel through **your** WebSocket server, on **your** domain, without transiting a third party. You decide who connects — via IP allowlist, OIDC SSO or HTTP Basic Auth in front of nginx. And since both components are published under the MIT licence, no commercial restriction applies regardless of how many clients or collaborators work on the instance.",{"type":38,"title":39,"items":40},"ul","Concrete benefits",[41,42,43,44,45,46],"**Zero software subscription** — both components (interface and collaboration server) are MIT. You pay for the VPS, nothing else.","**Mockup confidentiality** — drawing sessions stay on your infrastructure. No design file transits a third party.","**Access under your control** — IP allowlist, OIDC SSO or HTTP Basic Auth in front of nginx depending on the required isolation level.","**Sessions and members scale with VPS RAM** — no per-plan cap; the only limit is server RAM, and `excalidraw-room` is a lightweight Node.js service.","**Optional persistence** — mount a Docker volume or connect an S3-compatible bucket to archive boards exported as JSON.","**Integration into a self-hosted stack** — an Excalidraw instance alongside Penpot, Mattermost or Docmost closes the SaaS perimeter for an entire agency.",{"type":34,"title":48,"body":49},"Architecture: two containers, distinct roles","Excalidraw splits what most people consider a single tool into two independent components:\n\n- **`excalidraw\u002Fexcalidraw`** — the compiled React interface, served as a static site by nginx inside the container. It runs no application server. Its only constraint is the `VITE_APP_WS_SERVER_URL` variable, which must point to your room server at **compile time**. This variable is baked into the JavaScript bundle: changing it on a running container has no effect.\n\n- **`excalidraw\u002Fexcalidraw-room`** — a Node.js Socket.IO server that relays drawing events in memory between participants in the same session. It is **stateless**: it persists nothing and forgets everything on restart. Drawings live in browser `localStorage` or are manually exported.\n\nPractical consequence: the official Docker image hard-codes the Excalidraw collaboration server URL. To redirect to your own `excalidraw-room`, you must **build your own image** with `VITE_APP_WS_SERVER_URL` set to your domain — or use an entrypoint that patches the bundle at startup.",{"type":34,"title":51,"body":52},"Prerequisites","The ServOrbit Start VPS (2 vCPU, 4 GB RAM) covers the standard case: the static interface is nearly zero-load, and `excalidraw-room` consumes less than 256 MB under normal traffic. With ten concurrent collaborators, you will stay well under half the available RAM.\n\n**What you need before starting:**",{"type":38,"title":54,"items":55},"Prerequisites checklist",[56,57,58,59,60],"A VPS with at least 1 vCPU and 512 MB RAM (1 GB recommended for a team).","Docker Engine and Docker Compose Plugin installed (`docker compose version` to verify).","A domain name pointed at the VPS IP — without TLS, WebSockets are blocked by modern browsers.","Root SSH access or a user with `sudo` rights.","A valid TLS certificate — ServOrbit configures Let's Encrypt automatically.",{"type":62,"title":63,"steps":64},"steps","Deploy Excalidraw in 5 steps",[65,68,71,74,77],{"title":66,"body":67},"Create the VPS and install Docker","Provision an Ubuntu 24.04 VPS from your ServOrbit dashboard. Once connected over SSH, if Docker is not yet installed, run:\n\n```bash\ncurl -fsSL https:\u002F\u002Fget.docker.com | sh\n```\n\nVerify Docker Compose Plugin responds before continuing:\n\n```bash\ndocker compose version\n```",{"title":69,"body":70},"Build the image with your collaboration URL","Clone the official repository, then build the image substituting your domain. Replace `collab.yourdomain.com` with the subdomain you allocate to `excalidraw-room`:\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002Fexcalidraw\u002Fexcalidraw.git\ncd excalidraw\ndocker build \\\n  --build-arg VITE_APP_WS_SERVER_URL=wss:\u002F\u002Fcollab.yourdomain.com \\\n  -t my-excalidraw:latest .\n```\n\nThis step bakes the WebSocket server URL into the JavaScript bundle. If you change domains later, you will need to rebuild. The official `excalidraw\u002Fexcalidraw` image works for local testing but points to Excalidraw's public server — unusable for a sovereign deployment.",{"title":72,"body":73},"Write the docker-compose.yml file","Create a working directory and write the following file. Both services listen internally; nginx (next step) is the only public entry point:\n\n```bash\nmkdir ~\u002Fexcalidraw-stack && cd ~\u002Fexcalidraw-stack\n```\n\n`docker-compose.yml` contents:\n\n```bash\nservices:\n  excalidraw:\n    image: my-excalidraw:latest\n    restart: unless-stopped\n    networks:\n      - excalidraw\n\n  excalidraw-room:\n    image: excalidraw\u002Fexcalidraw-room:latest\n    restart: unless-stopped\n    networks:\n      - excalidraw\n\nnetworks:\n  excalidraw:\n```\n\nStart the stack:\n\n```bash\ndocker compose up -d\n```",{"title":75,"body":76},"Configure nginx with WebSocket headers","This is the step where most deployments silently fail: without the `Upgrade` and `Connection` headers, the browser opens a plain HTTP connection instead of a WebSocket, and collaboration appears not to work with no visible error message.\n\nnginx block for the Excalidraw frontend (`draw.yourdomain.com`):\n\n```bash\nserver {\n    listen 443 ssl;\n    server_name draw.yourdomain.com;\n\n    location \u002F {\n        proxy_pass http:\u002F\u002Fexcalidraw:80;\n        proxy_set_header Host $host;\n    }\n}\n```\n\nnginx block for the room server (`collab.yourdomain.com`):\n\n```bash\nserver {\n    listen 443 ssl;\n    server_name collab.yourdomain.com;\n\n    location \u002F {\n        proxy_pass http:\u002F\u002Fexcalidraw-room:80;\n        proxy_http_version 1.1;\n        proxy_set_header Upgrade $http_upgrade;\n        proxy_set_header Connection \"upgrade\";\n        proxy_set_header Host $host;\n        proxy_read_timeout 86400s;\n    }\n}\n```\n\nReload nginx (`nginx -s reload`) after placing the blocks.",{"title":78,"body":79},"Test real-time collaboration","Open `https:\u002F\u002Fdraw.yourdomain.com` in two tabs or two different browsers. In the toolbar, click **Live collaboration** and create a session. Copy the session link into the second tab.\n\nDraw something in the first tab: the stroke should appear in the second in real time. If it does not, check the WebSocket headers in nginx first (browser network devtools show whether the connection upgraded to `101 Switching Protocols`). A `200` status on the WebSocket request means nginx did not pass the `Upgrade` headers.",{"type":81,"title":82,"body":83},"tip","Board persistence: two approaches","By default, `excalidraw-room` is fully stateless. If the server restarts, the current session is lost — but each participant retains locally what they drew in `localStorage`.\n\n**Option 1 — Automatic JSON export.** Configure a cron job or script that calls Excalidraw's export API and saves `.excalidraw` files to a Docker volume. These files can be re-imported at any time from the interface.\n\n**Option 2 — S3-compatible bucket.** ServOrbit offers S3-compatible object storage. Connect your bucket as the archive destination for exports; restoration after a failure is a single re-import of the last saved file.",{"type":85,"title":86,"headers":87,"rows":92},"comparison","Self-hosted Excalidraw vs SaaS alternatives",[88,89,90,91],"Criteria","Excalidraw (self-hosted)","Miro","FigJam",[93,97,102,106,110,114],[94,95,96,96],"Cost per user","None (VPS only)","Paid per seat",[98,99,100,101],"Data hosted at","Your infrastructure","Miro Inc.","Adobe \u002F Figma",[103,104,105,105],"Concurrent members","RAM-bound","Plan-limited",[107,108,109,109],"Software licence","MIT (open source)","Proprietary",[111,112,113,113],"Self-hostable","Yes, two containers","No",[115,116,117,118],"Access control","IP \u002F SSO \u002F Basic Auth","SSO (Pro plans)","SSO (Edu+ plans)",{"type":34,"title":120,"body":121},"Going further: SSO and IP allowlists","For an agency whose clients have strict confidentiality requirements, exposing Excalidraw on a public subdomain is not always acceptable. Two common configurations harden access without modifying Excalidraw itself.\n\n**HTTP Basic Auth via nginx.** Add an `auth_basic` directive in front of the frontend `location \u002F` block. Anyone attempting to open the interface must authenticate before the React app even loads. Simple to set up, sufficient for internal projects.\n\n**IP allowlist.** If collaborators connect from fixed IPs or a corporate VPN, an `allow`\u002F`deny` block in nginx is enough to close the instance to the rest of the Internet:\n\n```bash\nallow 203.0.113.0\u002F24;\nallow 198.51.100.42;\ndeny all;\n```\n\n**OIDC SSO via an authenticating reverse proxy.** For teams that already have an identity provider (Keycloak, Authelia, Authentik), an authenticating proxy such as Oauth2-Proxy or Authelia placed in front of nginx delegates authentication to the existing SSO. Excalidraw does not need to know that an additional auth layer exists.",{"type":34,"title":123,"body":124},"Integration in a self-hosted stack","Excalidraw integrates naturally into a self-hosted tool stack. If you have already deployed Mattermost for team communication, you can paste an Excalidraw session link into a channel and invite collaborators to join the board directly. If Penpot covers high-fidelity design, Excalidraw handles upstream work — quick wireframes, flow diagrams and brainstorming sessions — before designs enter Penpot.\n\nThis complementarity is the real argument against SaaS: each tool stays within its area of expertise, without a platform subscription billing for features you do not need.","One platform for your VPS, domain and backups","ServOrbit brings VPS, domain and backups together in a single agency workspace: deploy Excalidraw for your team and manage your clients' infrastructure from the same dashboard.","Discover the agency workspace","\u002Fsolutions\u002Fagences",[130,153,172],{"id":131,"slug":132,"slugs":133,"title":137,"excerpt":138,"readTime":139,"views":16,"isPinned":17,"publishedAt":140,"updatedAt":141,"category":142,"categories":147,"featuredImage":28,"bgImage":29,"posterImage":149,"relatedSolution":150},193,"self-host-penpot-open-source-figma-alternative-on-your-vps",{"fr":134,"en":132,"ar":135,"es":136},"self-host-penpot-vps","استضافة-penpot-على-vps-بديل-figma-مفتوح-المصدر","alojar-penpot-en-un-vps","Self-host Penpot: open-source Figma alternative on your VPS","Deploy Penpot on a ServOrbit VPS for a full collaborative design tool — vector prototyping, components, developer handoff — no Figma subscription, no third-party data.",4,"2026-07-27T00:00:00+00:00","2026-09-11T11:34:11+00:00",{"id":139,"name":143,"slug":144,"color":145,"icon":146},"Development","developpement","bg-warning\u002F10 text-warning","dev",[148],{"id":139,"name":143,"slug":144,"color":145,"icon":146},"\u002Fblog\u002Fcovers\u002Fself-host-penpot-vps-poster.svg",{"categorySlug":151,"appSlug":152},"collaboration-productivity","penpot",{"id":154,"slug":155,"slugs":156,"title":160,"excerpt":161,"readTime":162,"views":163,"isPinned":17,"publishedAt":164,"updatedAt":165,"category":166,"categories":167,"featuredImage":28,"bgImage":29,"posterImage":169,"relatedSolution":170},76,"host-mattermost-on-your-own-vps",{"fr":157,"en":155,"ar":158,"es":159},"heberger-mattermost","استضافة-mattermost-على-خادم-vps-الخاص-بك","alojar-mattermost-en-un-vps","Host Mattermost on your own VPS","Complete 2026 guide: deploy Mattermost v10\u002Fv11 on VPS with Docker, PostgreSQL, SSL, integrations and backups. Self-hosted alternative to Slack.",9,2,"2026-04-05T00:00:00+00:00","2026-09-07T11:26:10+00:00",{"id":21,"name":22,"slug":23,"color":24,"icon":25},[168],{"id":21,"name":22,"slug":23,"color":24,"icon":25},"\u002Fblog\u002Fcovers\u002Fheberger-mattermost-poster.svg",{"categorySlug":23,"appSlug":171},"mattermost",{"id":173,"slug":174,"slugs":175,"title":179,"excerpt":180,"readTime":181,"views":16,"isPinned":17,"publishedAt":182,"updatedAt":165,"category":183,"categories":184,"featuredImage":28,"bgImage":29,"posterImage":186,"relatedSolution":187},302,"planka-self-host-an-open-source-kanban-board-on-your-vps",{"fr":176,"en":174,"ar":177,"es":178},"self-host-planka-vps","planka-نشر-لوحة-kanban-مفتوحة-المصدر-على-vps","planka-tablero-kanban-open-source-autoalojado-en-vps","Planka: Self-Host an Open-Source Kanban Board on Your VPS","Planka: self-hosted Kanban board for dev teams. Open-source alternative to Trello (AGPL), ~12k GitHub stars — deploy on your VPS in minutes.",3,"2026-01-13T00:00:00+00:00",{"id":21,"name":22,"slug":23,"color":24,"icon":25},[185],{"id":21,"name":22,"slug":23,"color":24,"icon":25},"\u002Fblog\u002Fcovers\u002Fself-host-planka-vps-poster.svg",{"categorySlug":151,"appSlug":188},"planka",1789126850971]