eleven / ocho Public
π€ Self-hosting Eleven
Run your own Eleven server: end-to-end-encrypted group chat where your box never sees a message β the server stores only ciphertext, and every key stays on your members' devices. One static binary, one directory of state, automatic TLS, automatic updates.
> This page is published as the README of > elevenmessenger/releases > (the public downloads repo). Its source of truth is docs/self-hosting.md > in the main repo.
What you need
- A Linux box: Ubuntu or Debian with systemd (what we test on),
x86_64orarm64, 1 GB RAM is plenty to start. A β¬4/month VPS works. - Root on it, with inbound ports 80 and 443 open.
- A domain (or subdomain) you can point at the box.
Install
curl -fsSL https://github.com/elevenmessenger/releases/releases/download/server/install.sh | sudo bashThat downloads the latest stable release for your architecture, verifies its published sha256, installs it at /opt/lchat/lchat, and bootstraps the box: a locked-down service user, systemd units, the TLS router on 80/443, and the hourly auto-update timer. (Prefer not to pipe to shell? Download install.sh from the same URL, read it β it's short β then run it.)
Create your first chat
Point a DNS A record at the box (chat.example.com β your box IP), then:
lchat add-instance chat.example.comIt prints a one-click setup link. Open it: you pick a name, your browser generates your keys (they never leave it), and Eleven walks you through naming the space and inviting people. The Let's Encrypt certificate issues automatically on the first request β no certbot, no reverse proxy.
Each add-instance creates a fully isolated chat: its own database, admin token, and subdomain. Run one for the family and another for the club; they share nothing.
What you get out of the box
- End-to-end encryption: messages, names, photos, and files are encrypted on devices; the server relays and stores ciphertext. If your box is compromised, the attacker gets nothing readable.
- Web app + notifications: members use it from any browser; web push notifications work with zero configuration.
- Automatic updates: the box checks our signed release feed hourly and applies stable-channel updates with a health check and automatic rollback. Each chat's admin can change channel (stable/beta/edge) or turn auto-updates off in the admin panel;
lchat update statusshows the fleet. - Bots, optionally with AI:
lchat bot provision+lchat bot run(same binary, no other runtime) adds the built-in helpers β Eleven welcomes new members and answers slash commands. SetANTHROPIC_API_KEYand they get a brain; without it they're deterministic helpers. Seedocs/bots.md.
Honest limitations
- Native app push: members can use the Eleven iOS/Mac apps against your server, but native push notifications route through Apple via our central relay, which needs a per-server token we mint. Web push is unaffected. If you want native push for your server, ask us for a relay token (open an issue on this repo) β self-serve is planned.
- Passkey backup routes through us by default: the optional "save a passkey" account backup enrolls against our home server (
home.elevenmessenger.com). What's stored there is passkey-encrypted β we can't read it β but if you'd rather keep even that ciphertext on your own hardware, run thehomeservice yourself and setLCHAT_HOME_ORIGINin the instance's/data/<host>.env. - The trust root for updates is ours: auto-updates install binaries we sign. That's the point of the channels β but if you fork, build your own binary with your own key and feed URL (
LCHAT_UPDATE_MANIFEST_URL).
Operating it
- Everything lives in
/dataβ databases, TLS certs, tokens, env files. Back that directory up and you can rebuild the box from scratch. (For continuous backups, Litestream replicating/data/*.dbto object storage works well; the installer doesn't set this up for you.) - Updates: automatic.
lchat update statusshows every chat's channel and version;lchat update run --dry-runpreviews a pass; a bad release rolls itself back. Re-running the install one-liner also updates immediately and refreshes the systemd units. - Admin access:
lchat admin-link chat.example.comre-prints a chat's admin URL (it's also in/data/<host>.env). - Remove a chat:
lchat remove chat.example.com --stopstops it and unroutes it; its database stays in/datauntil you delete it yourself β removal never destroys data. - Hardening: the units are already sandboxed; for the box itself, a firewall (22/80/443), key-only SSH, and unattended OS upgrades are the standard trio. Going further is optional: our own fleet closes public port 22 entirely β SSH rides a WireGuard tunnel (invisible to scanners), root login is disabled after first setup, and day-to-day admin runs through named accounts with a committed sudo allowlist. The full recipe, including the break-glass path via your provider's rescue console, is in
docs/instance-router.md Β§ Hardeningin the main repo.
Scaling up (optional)
The same binary contains the multi-tenant machinery we run 11ch.at with β a self-serve provisioner, wildcard DNS-01 certificates (LCHAT_WILDCARD_DOMAINS + a DNSimple token), and a central home server. None of it is needed for a personal box; the design docs live in the main repo under docs/.