---
title: "Deploy Tela | (Just Updated) Markdown Team Wiki With Built-In MCP Server And REST API, Admin Generated"
description: "Tela markdown team wiki with built-in MCP server, REST API and Postgres"
category: "Other"
url: https://railway.com/deploy/tela-or-just-updated-markdown-team-wiki-
---

# 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 on Railway](https://railway.com/template/tela-or-just-updated-markdown-team-wiki-)**

Machine-readable deploy manifest (JSON, validated by TemplateCI): https://railway.com/deploy/tela-or-just-updated-markdown-team-wiki-/manifest.json

- **Creator:** SuperSlowSloth
- **Category:** Other

## Template content

### backend

- **Image:** ghcr.io/zcag/tela-backend:0.11.3@sha256:8665ef9e0dcaae0989d1413ae3690710c8bafeffed996628330f8c009e2b69de
- **Start command:** `/bin/sh -c 'echo ZXhwb3J0IFRFTEFfQURNSU5fVVNFUk5BTUU9YWRtaW4KZXhwb3J0IFRFTEFfUkVHSVNUUkFUSU9OX09QRU49ZmFsc2UgVEVMQV9VUERBVEVfQ0hFQ0s9MApleHBvcnQgVEVMQV9HT1RFTkJFUkdfVVJMPWh0dHA6Ly9nb3RlbmJlcmcucmFpbHdheS5pbnRlcm5hbDozMDAwCmV4cG9ydCBURUxBX1BERl9SRU5ERVJfQkFTRV9VUkw9aHR0cDovL3Byb3h5LnJhaWx3YXkuaW50ZXJuYWw6ODA4MApleHBvcnQgVEVMQV9ERUNLX1VSTD1odHRwOi8vZGVjay5yYWlsd2F5LmludGVybmFsOjMzNDQKaT0wCnVudGlsIG5jIC16IC13IDIgcG9zdGdyZXMucmFpbHdheS5pbnRlcm5hbCA1NDMyIDI+L2Rldi9udWxsOyBkbwogIGk9JCgoaSsxKSk7IFsgIiRpIiAtZ3QgOTAgXSAmJiB7IGVjaG8gImJhY2tlbmQ6IHBvc3RncmVzIG5ldmVyIGFuc3dlcmVkIjsgYnJlYWs7IH0KICBzbGVlcCAyCmRvbmUKZWNobyAiYmFja2VuZDogcG9zdGdyZXMgcmVhY2hhYmxlIGFmdGVyICRpIHRyaWVzIgpleGVjIC90ZWxh | base64 -d > /tmp/boot.sh; exec sh /tmp/boot.sh'`

### proxy

- **Image:** ghcr.io/zcag/tela-proxy:0.11.3@sha256:679e2a95545b7817b3d24f3aa63cb4d83247f152964f41676a8b947d51ac9ee0
- **Start command:** `/bin/sh -c 'echo ZXhwb3J0IFRFTEFfU0lURV9BRERSRVNTPSI6JHtQT1JUOi04MDgwfSIKZXhwb3J0IFRFTEFfVVBTVFJFQU1fQkFDS0VORD1iYWNrZW5kLnJhaWx3YXkuaW50ZXJuYWw6ODA4MApleHBvcnQgVEVMQV9VUFNUUkVBTV9GUk9OVEVORD1mcm9udGVuZC5yYWlsd2F5LmludGVybmFsOjgwODAKZWNobyAicHJveHk6IGxpc3Rlbj0kVEVMQV9TSVRFX0FERFJFU1MiCmV4ZWMgY2FkZHkgcnVuIC0tY29uZmlnIC9ldGMvY2FkZHkvQ2FkZHlmaWxlIC0tYWRhcHRlciBjYWRkeWZpbGU= | base64 -d > /tmp/boot.sh; exec sh /tmp/boot.sh'`
- **Public domain:** Yes

### deck

- **Image:** ghcr.io/zcag/tela-deck:0.11.3@sha256:77d3d2532f64ecca582eb66b2d948fc171363286119f2e04918418a80a96da53
- **Start command:** `/bin/sh -c 'echo ZXhwb3J0IFBPUlQ9MzM0NApleGVjIG5vZGUgc2VydmVyLm1qcw== | base64 -d > /tmp/boot.sh; exec sh /tmp/boot.sh'`

### gotenberg

- **Image:** gotenberg/gotenberg:8.40.0@sha256:53073e798c8ef39ea2187e44cb67bab77894ea2509100b94c4fe3b461f7b2996

### postgres

- **Image:** pgvector/pgvector:pg17@sha256:b513c48566e4777cd3370451400000c78eda6a08131d68f4c31d4a76f27bd8fd
- **Start command:** `/bin/sh -c 'echo ZXhwb3J0IFBPU1RHUkVTX1VTRVI9dGVsYSBQT1NUR1JFU19EQj10ZWxhCmV4ZWMgZG9ja2VyLWVudHJ5cG9pbnQuc2ggcG9zdGdyZXM= | base64 -d > /tmp/boot.sh; exec sh /tmp/boot.sh'`

### frontend

- **Image:** ghcr.io/zcag/tela-frontend:0.11.3@sha256:b81279c692f35b8194c79f2f7026fa6055982805b076e3512f22d68501e0432c
- **Start command:** `/bin/sh -c 'echo ZXhwb3J0IFRFTEFfQkFDS0VORD1iYWNrZW5kLnJhaWx3YXkuaW50ZXJuYWw6ODA4MApOUz0kKGF3ayAnL15uYW1lc2VydmVyL3twcmludCAkMjsgZXhpdH0nIC9ldGMvcmVzb2x2LmNvbmYpClsgLW4gIiROUyIgXSB8fCBOUz1mZDEyOjoxMApjYXNlICIkTlMiIGluICo6KikgTlM9IlskTlNdIjs7IGVzYWMKZXhwb3J0IFRFTEFfUkVTT0xWRVI9IiROUyIKVD0vZXRjL25naW54L3RlbXBsYXRlcy9kZWZhdWx0LmNvbmYudGVtcGxhdGUKc2VkIC1pICdzLyBpcHY2PW9mZi8vZzsgcy9eXCggKlwpbGlzdGVuIDgwOy9cMWxpc3RlbiA4MDgwO1xuXDFsaXN0ZW4gWzo6XTo4MDgwOy8nICIkVCIKZWNobyAiZnJvbnRlbmQ6IGxpc3Rlbj04MDgwIHJlc29sdmVyPSROUyIKZXhlYyAvZG9ja2VyLWVudHJ5cG9pbnQuc2ggbmdpbnggLWcgImRhZW1vbiBvZmY7Ig== | base64 -d > /tmp/boot.sh; exec sh /tmp/boot.sh'`

## Documentation

# 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

```bash
#!/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

- [Tela repository](https://github.com/zcag/tela)
- [Tela documentation](https://github.com/zcag/tela#readme)


## Similar templates

- [Rocky Linux](https://railway.com/deploy/rocky-linux) — Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀
- [Foundry Virtual Tabletop](https://railway.com/deploy/X5tR6G) — A Self-Hosted & Modern Roleplaying Platform
- [Letta Code Remote](https://railway.com/deploy/letta-code-remote) — Run a Letta Code agent 24/7. No inbound ports, just deploy.

Open this page in a browser: https://railway.com/deploy/tela-or-just-updated-markdown-team-wiki-
