Blog / Tutorials

Self-Host Matrix (Synapse) on a VPS — Your Own Private Chat Server

By the NoctHost TeamAugust 7, 20263 min read

Matrix is an open, federated chat protocol — think of it as email for real-time messaging: anyone can run a server, and servers talk to each other. Synapse is the reference homeserver. Run it yourself and you get end-to-end-encrypted group chat and calls on infrastructure you own, with no company reading your metadata.

This guide stands up a working Synapse homeserver with HTTPS in about fifteen minutes.

A Note on the Domain

Matrix uses two names: the server name (the part after the colon in @user:example.com) and the actual hostname Synapse runs on. Keeping them the same domain is simplest. This guide assumes you own example.com and will serve Synapse at matrix.example.com, with the server name delegated to it.

Step 1: Install Docker

curl -fsSL https://get.docker.com | sh

Step 2: Generate the Config

Synapse ships a one-shot generator. Run it to create the config, then edit it:

mkdir -p synapse-data
docker run --rm \
  -v $(pwd)/synapse-data:/data \
  -e SYNAPSE_SERVER_NAME=example.com \
  -e SYNAPSE_REPORT_STATS=no \
  matrixdotorg/synapse:latest generate

Step 3: Compose with Caddy HTTPS

Save as docker-compose.yml:

services:
  synapse:
    image: matrixdotorg/synapse:latest
    restart: always
    volumes:
      - ./synapse-data:/data

  caddy:
    image: caddy:2-alpine
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
    depends_on:
      - synapse

volumes:
  caddy_data:

Step 4: The Caddyfile (with Delegation)

The extra example.com block tells other servers where to find yours (well-known delegation), so your user IDs can be the clean @you:example.com:

matrix.example.com {
  reverse_proxy synapse:8008
}

example.com {
  handle /.well-known/matrix/server {
    header Content-Type application/json
    respond `{"m.server": "matrix.example.com:443"}`
  }
}

Bring it up:

docker compose up -d

Step 5: Create Your Account

Registration is closed by default (good). Create your admin user from the command line:

docker compose exec synapse register_new_matrix_user -c /data/homeserver.yaml http://localhost:8008

Now log in with any Matrix client (Element is the popular one), using matrix.example.com as the homeserver. Turn on end-to-end encryption in your rooms and you have private chat no platform can read.

Tip — Leave open registration off. An open Synapse gets abused for spam across the federation fast — create accounts manually or add email verification if you need self-signup.

What It Costs

A personal or small-group Synapse runs on the Standard plan (2 vCPU, 4 GB); federation and media add some load, so give it a little headroom. On NoctHost that is hourly billing from a prepaid balance topped up with crypto — no card, no KYC — which matches the point of running your own chat server: no company in the middle.

Spin one up in about a minute

Email signup, pay with crypto, hourly billing. Trying a box costs cents — destroy it when you are done.

Deploy a server

Frequently asked

Is self-hosted Matrix actually private?
Messages in encrypted rooms are end-to-end encrypted, so even you as the server operator cannot read them. You do control metadata (who talks to whom, when), which is exactly why self-hosting beats a hosted server for privacy.
Do I have to federate with the public network?
No. You can disable federation entirely for a closed, private server, or keep it on to chat with users on other homeservers. It is a config toggle.
How much maintenance is Synapse?
Modest — occasional docker compose pull updates and keeping an eye on disk (media grows). A small homeserver is not high-maintenance once it is running.
Can I use Element and other apps?
Yes. Any Matrix client (Element on web, desktop and mobile, plus alternatives) connects to your homeserver — you are not locked into one app.

Keep reading