Updated README.md.
This commit is contained in:
269
README.md
269
README.md
@@ -0,0 +1,269 @@
|
||||
# Matrix / Element Self-Hosted Server
|
||||
|
||||
A Docker Compose setup for running a self-hosted [Matrix](https://matrix.org/) homeserver (Synapse) with the [Element Web](https://element.io/) client and a Synapse admin panel.
|
||||
|
||||
## What's included
|
||||
|
||||
| Service | Image | Default Port | Purpose |
|
||||
|---|---|---|---|
|
||||
| **Synapse** | `matrixdotorg/synapse:latest` | `8008` | Matrix homeserver |
|
||||
| **Element Web** | `vectorim/element-web:latest` | `8080` | Web chat client |
|
||||
| **Synapse Admin** | `awesometechnologies/synapse-admin:latest` | `8081` | Admin UI |
|
||||
| **PostgreSQL** | `postgres:14` | `5432` | Database for Synapse |
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [Docker](https://docs.docker.com/get-docker/) and [Docker Compose](https://docs.docker.com/compose/install/)
|
||||
- A domain name pointed at your server (e.g. `chat.example.com`)
|
||||
- A reverse proxy (nginx, Caddy, Traefik, etc.) to handle TLS termination — the containers themselves do not manage HTTPS
|
||||
|
||||
---
|
||||
|
||||
## Setup
|
||||
|
||||
### 1. Clone the repository
|
||||
|
||||
```bash
|
||||
git clone <your-repo-url>
|
||||
cd matrix
|
||||
```
|
||||
|
||||
### 2. Configure environment variables
|
||||
|
||||
Copy the example env file and edit it:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Open `.env` and set each value:
|
||||
|
||||
```dotenv
|
||||
# PostgreSQL
|
||||
POSTGRES_DB=synapse
|
||||
POSTGRES_USER=synapse
|
||||
POSTGRES_PASSWORD=<strong-random-password>
|
||||
|
||||
# Synapse — must match your public domain
|
||||
SYNAPSE_SERVER_NAME=chat.example.com
|
||||
|
||||
# Synapse Admin UI
|
||||
REACT_APP_SERVER=https://chat.example.com
|
||||
REACT_APP_REGISTRATION_ENABLED=false # set to true only if you want open registration
|
||||
```
|
||||
|
||||
> **Security note:** Use a strong, unique password for `POSTGRES_PASSWORD`. Never commit `.env` to version control — it is already in `.gitignore`.
|
||||
|
||||
### 3. Generate the Synapse configuration
|
||||
|
||||
Synapse needs a `homeserver.yaml` generated before it can start. Run this once:
|
||||
|
||||
```bash
|
||||
docker run --rm \
|
||||
-e SYNAPSE_SERVER_NAME=chat.example.com \
|
||||
-e SYNAPSE_REPORT_STATS=yes \
|
||||
-v "$(pwd)/synapse-data:/data" \
|
||||
matrixdotorg/synapse:latest generate
|
||||
```
|
||||
|
||||
Replace `chat.example.com` with your actual domain. This creates `synapse-data/homeserver.yaml`.
|
||||
|
||||
### 4. Point Synapse at PostgreSQL
|
||||
|
||||
Open `synapse-data/homeserver.yaml` and replace the default SQLite database block with:
|
||||
|
||||
```yaml
|
||||
database:
|
||||
name: psycopg2
|
||||
args:
|
||||
user: synapse
|
||||
password: <your-POSTGRES_PASSWORD>
|
||||
database: synapse
|
||||
host: postgres
|
||||
cp_min: 5
|
||||
cp_max: 10
|
||||
```
|
||||
|
||||
Use the same credentials you set in `.env`.
|
||||
|
||||
### 5. Configure the Element Web client
|
||||
|
||||
Copy the example config and edit it:
|
||||
|
||||
```bash
|
||||
cp element-config.json.example element-config.json
|
||||
```
|
||||
|
||||
Update every occurrence of `chat.example.com` to your domain:
|
||||
|
||||
```json
|
||||
{
|
||||
"default_server_config": {
|
||||
"m.homeserver": {
|
||||
"base_url": "https://chat.example.com",
|
||||
"server_name": "chat.example.com"
|
||||
}
|
||||
},
|
||||
"disable_custom_urls": true,
|
||||
"brand": "My Matrix Server",
|
||||
"showLabsSettings": true,
|
||||
"voip": {
|
||||
"stun_servers": [
|
||||
{ "urls": ["stun:turn.example.com:3478"] }
|
||||
],
|
||||
"turn_servers": [
|
||||
{
|
||||
"urls": [
|
||||
"turn:turn.example.com:3478?transport=udp",
|
||||
"turn:turn.example.com:3478?transport=tcp",
|
||||
"turns:turn.example.com:5349?transport=tcp"
|
||||
],
|
||||
"secret": "<your-turn-server-secret>",
|
||||
"expiry": 86400000
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you do not have a TURN server, remove the `voip` and `webrtc` blocks entirely. Voice/video calls on the same local network will still work without them.
|
||||
|
||||
### 6. Start the stack
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Verify all containers are running:
|
||||
|
||||
```bash
|
||||
docker compose ps
|
||||
```
|
||||
|
||||
Check Synapse logs for errors:
|
||||
|
||||
```bash
|
||||
docker compose logs -f synapse
|
||||
```
|
||||
|
||||
### 7. Create your first admin user
|
||||
|
||||
Once Synapse is running, register an admin account:
|
||||
|
||||
```bash
|
||||
docker compose exec synapse register_new_matrix_user \
|
||||
-c /data/homeserver.yaml \
|
||||
-u <username> \
|
||||
-p <password> \
|
||||
-a \
|
||||
http://localhost:8008
|
||||
```
|
||||
|
||||
The `-a` flag grants admin privileges. You can omit it for regular users.
|
||||
|
||||
---
|
||||
|
||||
## Reverse proxy / TLS
|
||||
|
||||
The containers expose plain HTTP. You must front them with a reverse proxy that terminates TLS. A minimal **nginx** example:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name chat.example.com;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/chat.example.com/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/chat.example.com/privkey.pem;
|
||||
|
||||
# Element Web
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8080;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
|
||||
# Synapse Matrix API and federation
|
||||
location /_matrix {
|
||||
proxy_pass http://127.0.0.1:8008;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
client_max_body_size 50M;
|
||||
}
|
||||
|
||||
location /_synapse {
|
||||
proxy_pass http://127.0.0.1:8008;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
For automatic TLS with Let's Encrypt, use [Certbot](https://certbot.eff.org/) or [Caddy](https://caddyserver.com/).
|
||||
|
||||
### Matrix federation (optional)
|
||||
|
||||
If you want other Matrix homeservers to be able to communicate with yours, port `8448` must be reachable publicly. You can either:
|
||||
|
||||
- Add a second `server { listen 8448 ssl; ... }` block that proxies to `http://127.0.0.1:8008`, or
|
||||
- Add a `.well-known/matrix/server` file served from your domain pointing federation to port 443
|
||||
|
||||
---
|
||||
|
||||
## Accessing the services
|
||||
|
||||
| URL | Service |
|
||||
|---|---|
|
||||
| `https://chat.example.com` | Element Web client |
|
||||
| `https://chat.example.com:8081` | Synapse Admin panel |
|
||||
| `https://chat.example.com/_matrix` | Matrix homeserver API |
|
||||
|
||||
Log into the admin panel at port `8081` using the admin credentials you created in step 7.
|
||||
|
||||
---
|
||||
|
||||
## Data persistence
|
||||
|
||||
All persistent data is stored in local directories that are bind-mounted into the containers:
|
||||
|
||||
| Directory | Contents |
|
||||
|---|---|
|
||||
| `postgres-data/` | PostgreSQL database files |
|
||||
| `synapse-data/` | Synapse config, media uploads, signing keys |
|
||||
|
||||
Both directories are excluded from git via `.gitignore`. **Back them up regularly.**
|
||||
|
||||
---
|
||||
|
||||
## Upgrading
|
||||
|
||||
Pull the latest images and recreate the containers:
|
||||
|
||||
```bash
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Check the [Synapse changelog](https://github.com/element-hq/synapse/blob/master/CHANGES.md) before upgrading major versions — some releases require manual migration steps.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Synapse fails to start with a database error**
|
||||
Make sure the credentials in `synapse-data/homeserver.yaml` match those in `.env`, and that the `postgres` service is fully healthy before Synapse starts. You can force the order with:
|
||||
```bash
|
||||
docker compose up -d postgres
|
||||
# wait a few seconds, then:
|
||||
docker compose up -d synapse element-web element-admin
|
||||
```
|
||||
|
||||
**Element Web shows "Homeserver is not reachable"**
|
||||
Verify that `base_url` in `element-config.json` uses `https://` and points to the domain your reverse proxy serves (not `localhost`).
|
||||
|
||||
**"M_FORBIDDEN" when registering users**
|
||||
Open registration is disabled by default. Either use the `register_new_matrix_user` command (step 7) or set `enable_registration: true` in `homeserver.yaml` and restart Synapse.
|
||||
|
||||
**Port conflicts**
|
||||
If any default port is already in use on your host, change the left side of the port mapping in `docker-compose.yml` (e.g. `"8082:80"` for Element Web) and update your reverse proxy accordingly.
|
||||
|
||||
Reference in New Issue
Block a user