Deploy Tela | (Just Updated) Markdown Team Wiki With Built-In MCP Server And REST API, Admin Generated

Tela markdown team wiki with built-in MCP server, REST API and Postgres

Deploy Tela | (Just Updated) Markdown Team Wiki With Built-In MCP Server And REST API, Admin Generated

Just deployed

Just deployed

Just deployed

Just deployed

Just deployed

/var/lib/postgresql

Just deployed

Deploy and Host Tela on Railway

Built for an LLM agent to deploy and use. The deploy form has nothing to fill in: the administrator password and the database password are generated, the administrator account is created at first boot, public signup is closed, and pages survive redeploys. Tela is an open-source markdown team wiki with a built-in MCP server, a REST API with an OpenAPI document, WebDAV, and PDF and slide-deck export.

About Hosting Tela

This template runs six services from the upstream Tela images (version 0.11.3), each pinned by digest. proxy is the public front door on one domain and routes /api to the backend and everything else to the web interface. frontend is the web interface. backend is the Go server: pages, spaces, the REST API, the MCP server at /api/mcp and WebDAV at /dav. postgres (pgvector) holds every page on a volume. gotenberg renders PDF export and deck renders slide decks, both private.

No default login. The administrator is the username admin, created at first boot from the generated TELA_ADMIN_PASSWORD with the email TELA_ADMIN_EMAIL (admin at the proxy domain, already verified). Registration is closed, so nobody else can create an account.

What the template fixes for Railway. Services reach each other over Railway's private network, which is IPv6, so the web interface listens on both IPv4 and IPv6 and resolves names through Railway's own DNS. The proxy listens on Railway's injected PORT. The backend waits for Postgres before it starts. The public address is set from the proxy domain so exported links point at the right host.

Using it. Open the proxy domain, sign in as admin with TELA_ADMIN_PASSWORD (read it from the backend service variables), then create a space and start writing. For an agent, mint an API key under settings or with the call below and point an MCP client at /api/mcp.

Agent contract

  • Public URL: https://RAILWAY_SERVICE_PROXY_URL (the generated domain of the proxy service, also the part of TELA_ADMIN_EMAIL after the at sign)
  • Private URL: http://proxy.railway.internal:8080 (the backend itself is http://backend.railway.internal:8080)
  • Credentials: the variable TELA_ADMIN_PASSWORD on the backend service
  • Login name: the username admin (fixed) and the variable TELA_ADMIN_EMAIL on the backend service (a public identifier, not a secret)
  • Auth: POST /api/auth/login with JSON identifier and password sets a session cookie; with that cookie POST /api/api_keys with {"name":"agent","scope":"write"} returns a key tela_pat_... once, in api_key.key. Every other /api call sends it as Authorization: Bearer KEY; the MCP server at /api/mcp takes the same key. A request with no key or a wrong one answers 401.
  • Health: GET /api/health returns 200
#!/bin/sh
# needs: TELA_ADMIN_EMAIL, TELA_ADMIN_PASSWORD (variables of the backend service); also curl. TELA_ADMIN_EMAIL is admin@ plus the proxy's public domain; the username is admin.
D="${TELA_ADMIN_EMAIL#admin@}"; R="https://$D"; J="Content-Type: application/json"; B=$(mktemp); C=$(mktemp)
n=0; until [ "$(curl -s -o /dev/null -w '%{http_code}' "$R/api/health")" = 200 ]; do n=$((n+1)); [ "$n" -le 90 ] || break; sleep 5; done
# sign in as the administrator created at first boot (a session cookie), then mint an API key for the agent
n=0; while :; do c=$(curl -s -c "$C" -o "$B" -w '%{http_code}' -H "$J" -d "{\"identifier\":\"admin\",\"password\":\"$TELA_ADMIN_PASSWORD\"}" "$R/api/auth/login"); if [ "$c" = 200 ]; then break; fi; n=$((n+1)); [ "$n" -le 12 ] || break; sleep 10; done
echo "login: $c"
curl -s -b "$C" -o "$B" -w "create key: %{http_code}\n" -H "$J" -d '{"name":"agent","scope":"write"}' "$R/api/api_keys"
K=$(sed -n 's/.*"key":"\(tela_pat_[^"]*\)".*/\1/p' "$B"); A="Authorization: Bearer $K"
S=$(curl -s -H "$A" "$R/api/spaces" | sed -n 's/.*"spaces":\[{"id":\([0-9]*\).*/\1/p')
curl -s -o /dev/null -w "read with key: %{http_code}\n" -H "$A" "$R/api/pages?space_id=$S"
curl -s -o "$B" -w "write with key: %{http_code}\n" -H "$A" -H "$J" -d "{\"space_id\":$S,\"title\":\"Railway Check\",\"body\":\"# Railway Check\"}" "$R/api/pages"
P=$(sed -n 's/.*"page":{"id":\([0-9]*\).*/\1/p' "$B")
curl -s -H "$A" "$R/api/pages?space_id=$S" | grep -c '"title":"Railway Check"' | sed 's/^/page found after write: /'
curl -s -o /dev/null -w "delete with key: %{http_code}\n" -X DELETE -H "$A" "$R/api/pages/$P"
curl -s -o /dev/null -w "read without key: %{http_code}\n" "$R/api/pages?space_id=$S"
curl -s -o /dev/null -w "write without key: %{http_code}\n" -X POST -H "$J" -d "{\"space_id\":$S,\"title\":\"Anonymous\",\"body\":\"x\"}" "$R/api/pages"
curl -s -o /dev/null -w "write wrong key: %{http_code}\n" -X POST -H "Authorization: Bearer wrong" -H "$J" -d "{\"space_id\":$S,\"title\":\"Anonymous\",\"body\":\"x\"}" "$R/api/pages"
curl -s -o /dev/null -w "public signup: %{http_code}\n" -X POST -H "$J" -d '{"username":"intruder","email":"x@example.com","password":"Intruder-pass-123"}' "$R/api/auth/register"
curl -s -o /dev/null -w "openapi: %{http_code}\n" "$R/openapi.json"

A fresh deploy prints login: 200, create key: 201, read with key: 200, write with key: 201, page found after write: 1 and delete with key: 204. The refusals print read without key: 401, write without key: 401, write wrong key: 401 and public signup: 403: a request with no key or a wrong one creates nothing, and nobody can register an account from outside. openapi: 200 is the full API description at /openapi.json.

Why Deploy Tela on Railway?

Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.

By deploying Tela on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.

  • Agent-ready - a generated administrator password, a contract block and one script that proves sign-in, key creation, an authenticated write, read-back and delete, and the refusal of a read and a write with no key or a wrong one.
  • No setup form and no default login - the administrator is created at boot and registration is closed.
  • Data survives redeploys - every page sits in Postgres on a volume.
  • Built-in MCP server - point an AI client at /api/mcp with the key.
  • Pinned - every upstream image is pinned by digest.

Common Use Cases

  • Team wiki and knowledge base - markdown pages in spaces with search and history.
  • Shared memory for AI agents - an agent reads and writes pages over the REST API or MCP.
  • Docs that export - pages to PDF and slide decks.
  • Self-hosted Notion or Confluence alternative - own the data, keep it on one domain.

Dependencies for Tela Hosting

  • The six services above, created by the template. Nothing else is required; outgoing email and sign-in providers can be configured inside Tela afterwards.

Deployment Dependencies


Template Content

More templates in this category

View Template
Rocky Linux
Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀

codestorm
51
View Template
Foundry Virtual Tabletop
A Self-Hosted & Modern Roleplaying Platform

Lucas
71
View Template
Letta Code Remote
Run a Letta Code agent 24/7. No inbound ports, just deploy.

Letta
52