# How to build your own [matrix] server [matrix] is an open protocol, not a product. Nobody owns it — not even us. Kubínska Scéna runs on exactly the same software you can install yourself, on your own machine, for free. This is a short, honest guide to doing it. None of it is a secret. If you ever leave the Scene, your accounts and rooms on another server keep working — [matrix] is not a walled garden. That is the whole point of an open protocol. ## What you’ll need - A server with a public IP address (the cheapest VPS will do, about €5 a month — Hetzner, DigitalOcean, OVH, or even an old computer at home that’s reachable from the internet) - Your own domain (e.g. `your-server.com`) - Docker and Docker Compose installed on the server - 20 minutes, and some patience the first time you start it up ## 1. DNS Point the domain (or a subdomain, e.g. `matrix.your-domain.com`) at the server’s IP address with an A record. Check it: ```bash dig +short matrix.your-domain.com ``` ## 2. Docker Compose Create a folder and put a `docker-compose.yml` in it: ```yaml services: postgres: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_USER: synapse POSTGRES_PASSWORD: change_this_password POSTGRES_DB: synapse POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C" volumes: - ./data/postgres:/var/lib/postgresql/data synapse: image: matrixdotorg/synapse:latest restart: unless-stopped depends_on: [postgres] environment: SYNAPSE_SERVER_NAME: your-domain.com SYNAPSE_REPORT_STATS: "no" volumes: - ./synapse:/data ports: - "127.0.0.1:8008:8008" caddy: image: caddy:2-alpine restart: unless-stopped ports: - "80:80" - "443:443" volumes: - ./Caddyfile:/etc/caddy/Caddyfile - ./caddy-data:/data ``` ## 3. Generate the basic configuration ```bash docker run -it --rm \ -v "$(pwd)/synapse:/data" \ -e SYNAPSE_SERVER_NAME=your-domain.com \ -e SYNAPSE_REPORT_STATS=no \ matrixdotorg/synapse:latest generate ``` This command creates `homeserver.yaml` and a signing key in the `synapse/` folder. In `homeserver.yaml`, switch the database connection to Postgres (by default it uses the simpler SQLite, which isn’t enough for production): ```yaml database: name: psycopg2 args: user: synapse password: change_this_password database: synapse host: postgres cp_min: 5 cp_max: 10 ``` ## 4. Reverse proxy with automatic TLS `Caddyfile`: ``` your-domain.com { reverse_proxy /_matrix/* synapse:8008 reverse_proxy /_synapse/client/* synapse:8008 } ``` Caddy gets its own certificate from Let’s Encrypt — no manual work with TLS. ## 5. Start it ```bash docker compose up -d ``` ## 6. Check federation (optional) If you want your server to talk to other [matrix] servers (federation), check your setup at . If you want a closed server — exactly like Kubínska Scéna — switch federation off in `homeserver.yaml`: ```yaml federation_domain_whitelist: [] ``` ## 7. Create your first account ```bash docker exec -it -synapse-1 register_new_matrix_user \ -c /data/homeserver.yaml http://localhost:8008 ``` ## 8. Connect Download [Element](https://element.io/download) (or FluffyChat, Cinny — you choose the client), and when you sign in, enter your own domain as the server, not matrix.org. ## Backups The database is backed up like any other Postgres: ```bash docker exec -postgres-1 pg_dump -U synapse synapse | gzip > backup.sql.gz ``` Set it up as a daily cron job. Don’t forget to back up the `synapse/` folder too (it holds the server’s signing key — without it, the server loses its identity). --- This is exactly the same software, and essentially the same procedure, that Kubínska Scéna runs on. No secret sauce. If you want to know more, the official Synapse documentation is at . *Kubínska Scéna, [matrix].kubinska-scena.life* *This is an English translation of the Slovak guide `/matrix/navod-vlastny-matrix-server.md`.*