Self-hosting requirements
Minimum specs for running tela on your own hardware, for a team of up to 10 people.
Required services
The docker compose up stack starts six containers. All six are required for a fully functional instance.
| Service | Image | Role | Idle RAM |
|---|---|---|---|
backend |
Go binary (built from source) | API, auth, migrations, MCP server | ~150–200 MB |
postgres |
pgvector/pgvector:pg17 |
Primary datastore (pages, users, sessions) | ~256–512 MB |
frontend |
nginx + static build | Serves the React SPA | ~50 MB |
proxy |
Caddy | TLS termination, routing, landing page | ~50 MB |
gotenberg |
gotenberg/gotenberg:8 |
PDF export (headless Chromium) | ~250 MB idle, ~500 MB per export |
deck |
Node.js / Vite | Deck slide rendering (Slidev) | ~200 MB idle, ~400 MB per compile |
[!NOTE] No
mem_limitis set in the compose file — Docker will use available system memory. The estimates above are typical RSS under light load for a small team.
Minimum recommended hardware (≤ 10 users)
| Resource | Minimum | Recommended |
|---|---|---|
| RAM | 2 GB | 4 GB |
| CPU | 2 vCPUs | 4 vCPUs |
| Disk | 10 GB | 20 GB |
RAM breakdown at 2 GB minimum: backend (~200 MB) + postgres (~400 MB) + frontend (~50 MB) + proxy (~50 MB) + gotenberg (~250 MB) + deck (~200 MB) = ~1.15 GB baseline, leaving ~850 MB headroom. That is workable for a small team with light concurrent use but leaves little room for a PDF or deck render burst. 4 GB is the comfortable operating point.
Disk: Docker images for all required services total roughly 3–4 GB. Allow 5–10 GB for PostgreSQL data growth (pages, attachments, RAG chunk vectors). Add more if you store binary file attachments.
Optional: Ollama embedder (semantic search)
Semantic search ("ask your docs") and Atlas (automated docs from a git repo) require an embedder. Without one, full-text keyword search still works — only /api/rag/* endpoints return 503.
| Resource | Additional requirement |
|---|---|
| RAM | +2–4 GB for the embedding model in memory |
| CPU | Fast multi-core CPU; GPU strongly recommended for acceptable throughput |
| Disk | +1–2 GB for the model weights |
The recommended model is qwen3-embedding:0.6b (1024-d). Pull it once after starting the profile:
docker compose --profile embed up -d
docker compose exec ollama ollama pull qwen3-embedding:0.6b
Then set TELA_RAG_EMBED_URL=http://ollama:11434 in deploy/.env.
[!TIP] An Ollama embedder does not need to run on the same host. Point
TELA_RAG_EMBED_URLat any reachable Ollama server. If the embedder host is on a private overlay network (VPN/Tailnet) and the backend runs in Docker, use the host's overlay IP address, not its hostname — the hostname may not resolve inside the container.
Summary: required vs optional
| Component | Required | What breaks without it |
|---|---|---|
| PostgreSQL | Yes | Nothing works |
| Go backend | Yes | Nothing works |
| Caddy proxy | Yes | No HTTP routing |
| React frontend | Yes | No web UI (API still works) |
| Gotenberg | No* | PDF export fails |
| Deck sidecar | No* | Deck pages can't render slides or export |
| Ollama (embedder) | No | Semantic search, "Ask", Atlas return 503; keyword search still works |
| SMTP | No | Email verification + password reset disabled; emailed links are logged instead |
* Gotenberg and the deck sidecar are started unconditionally by the default compose file but the app degrades gracefully if they are unreachable (export endpoints return an error). They can be omitted in a minimal footprint setup by commenting them out.