Self-Hosting

Run your own tela. It's a Go + PostgreSQL + React stack shipped as a Docker Compose deployment behind a Caddy proxy — you need only Docker (the marketing landing builds inside the image, so no Node toolchain).

tela is AGPL-3.0; the "tela" name and logo are reserved trademarks.

Quick start

git clone https://github.com/zcag/tela && cd tela
make setup            # writes deploy/.env from the example with generated secrets
$EDITOR deploy/.env   # set TELA_PUBLIC_BASE_URL, admin creds, SMTP
make up               # build + start
make logs             # the bootstrap admin password prints here once

The stack publishes host port 8780 (Caddy → app). The first admin comes from TELA_ADMIN_USERNAME/PASSWORD/EMAIL on first boot — or, if you leave TELA_ADMIN_PASSWORD unset, from the /setup web wizard the fresh instance lands on.

Configuration

Everything is env-driven (deploy/.env; every variable is documented in .env.example). The ones that matter:

Variable Notes
TELA_PG_PASSWORD No default — required. make setup generates it.
TELA_PUBLIC_BASE_URL Must match how users reach the instance — it drives emailed links and the cookie Secure flag.
TELA_SHARE_SECRET, TELA_API_KEY_SECRET HMAC keys. Unset → generated and persisted on first boot (stable across restarts); set them to pin/rotate from the environment. Rotating them invalidates outstanding share cookies / PATs.
TELA_SMTP_* Required for a usable multi-user instance (see Email).
TELA_DATABASE_URL Auto-built from TELA_PG_* in this compose stack — set it only when pointing at an external Postgres.

The backend logs its effective config at boot (config: …) — check those lines first when something's off.

TLS

The proxy defaults to plain HTTP on :80 (published as 8780), correct behind an external terminator (Cloudflare, a load balancer) — point it at :8780 and set an https:// base URL. For direct TLS, set TELA_SITE_ADDRESS=your.domain, publish 80+443 on the proxy, and Caddy auto-provisions a certificate. Direct TLS is also the prerequisite for org [[Custom domains]] (on-demand cert issuance can't fire behind an external terminator).

[!WARNING] The login cookie is Secure only when TELA_PUBLIC_BASE_URL is https://. If it's https but you serve plain HTTP, browsers drop the cookie and login silently fails. Keep the scheme matched to how users connect.

Email

With TELA_SMTP_HOST unset, tela logs verify/reset links instead of sending them — fine for a single admin, but open self-registration is unusable without SMTP (confirmation links only hit the log). Configure TELA_SMTP_* for any multi-user instance; it works with any SMTP relay (e.g. Resend).

Registration policy

By default anyone can register. For a private or internal instance, close self-registration after the initial admin setup: go to Settings → Instance (as an instance admin) or call the admin API:

curl -s -X PATCH https://your.host/api/admin/settings \
  -H 'Authorization: Bearer tela_pat_…' \
  -H 'content-type: application/json' \
  -d '{"settings":{"registration_open":"false"}}'

File sync (WebDAV)

tela exposes a WebDAV surface at /dav/ so you can sync pages from rclone, Obsidian, or any WebDAV client using a Personal Access Token. See [[Sync your vault (WebDAV)]] for setup steps.

[!NOTE] If you run behind Cloudflare: CF's default WAF rules block non-standard HTTP methods (PROPFIND, MKCOL, MOVE, COPY, etc.). You need to add a WAF skip rule for /dav/* on your zone, or WebDAV will fail with 403 errors from CF's edge — not from tela.

WebDAV is on by default; disable it with TELA_WEBDAV_ENABLED=0 in deploy/.env.

Semantic search & AI

Full-text search works out of the box. Semantic search ("ask your docs") needs an embedder and an LLM — both ship dark (return 503) until configured.

[!NOTE] Changing the embed model means re-embedding everything: after editing TELA_RAG_EMBED_MODEL, run … exec backend /tela reindex-all (resumable).

Reliability & failover

AI endpoints are external — if one clogs (rate-limited, slow, or down), the features that depend on it degrade. To keep them up, run the optional relief proxy: make up-relief starts a LiteLLM proxy in front of chat and embeddings, each with a primary and a relief endpoint, so traffic fails over automatically when the primary clogs. Set the endpoints in deploy/.env (the AI relief proxy block in .env.example); a relief embedder must output the same dimension (1024) as the primary.

Either way, Settings → Insights → AI endpoints & reliability (instance admin) shows each service's live status, probe latency, and whether it's behind a relief pool — the at-a-glance view of what's happening. Set TELA_GRAFANA_AI_URL to deep-link the card to a Grafana dashboard for the deeper per-endpoint failover metrics.

AI agents (MCP)

tela has a built-in MCP server at /api/mcp. Connect Claude, Claude Code, or any MCP client to https://your.host/api/mcp with a PAT as the bearer token. See [[Using the MCP server]] for tool reference and client setup.

Backups & upgrades

make backup                       # → ./backups/tela-<timestamp>.sql
make restore FILE=backups/...     # restore a dump

Upgrade with git pull && make up — migrations run automatically on boot (forward-only). Back up before upgrading.

Operations