# Matrix Synapse Setup

This VM runs **two Matrix Synapse instances**:

| Instance | server_name | Domain | Federation | Purpose |
|----------|-------------|--------|------------|---------|
| **Primary** | `mx.vish.gg` | https://mx.vish.gg | ✅ Yes | Main server with federation |
| **Legacy** | `vish` | https://matrix.thevish.io | ❌ No | Historical data archive |

## Architecture

```
                         Internet
                            │
                   ┌────────┴────────┐
                   │   Cloudflare    │
                   └────────┬────────┘
                            │
              ┌─────────────┴─────────────┐
              │                           │
              ▼                           ▼
    ┌─────────────────┐         ┌─────────────────┐
    │  mx.vish.gg     │         │ matrix.thevish.io│
    │  (port 443)     │         │  (port 443)      │
    └────────┬────────┘         └────────┬─────────┘
             │                           │
             ▼                           ▼
    ┌─────────────────┐         ┌─────────────────┐
    │ Synology Reverse│         │ Synology Reverse│
    │ Proxy → :8082   │         │ Proxy → :8081   │
    └────────┬────────┘         └────────┬─────────┘
             │                           │
             └───────────┬───────────────┘
                         │
                         ▼
              ┌─────────────────────────────────────┐
              │        Ubuntu VM (192.168.0.154)    │
              │  ┌──────────────┐ ┌──────────────┐  │
              │  │ Nginx :8082  │ │ Nginx :8081  │  │
              │  │ mx.vish.gg   │ │ thevish.io   │  │
              │  └──────┬───────┘ └──────┬───────┘  │
              │         │                │          │
              │         ▼                ▼          │
              │  ┌──────────────┐ ┌──────────────┐  │
              │  │ Synapse:8018 │ │ Synapse:8008 │  │
              │  │ mx.vish.gg   │ │ vish         │  │
              │  └──────┬───────┘ └──────┬───────┘  │
              │         │                │          │
              │         ▼                ▼          │
              │  ┌──────────────┐ ┌──────────────┐  │
              │  │ synapse_mx   │ │ synapse      │  │
              │  │ PostgreSQL   │ │ PostgreSQL   │  │
              │  └──────────────┘ └──────────────┘  │
              └─────────────────────────────────────┘
```

## Primary Server: mx.vish.gg

**This is the main server with federation enabled.**

### Configuration

- **Location**: `/opt/synapse-mx/`
- **Config**: `/opt/synapse-mx/homeserver.yaml`
- **Signing Key**: `/opt/synapse-mx/mx.vish.gg.signing.key`
- **Media Store**: `/opt/synapse-mx/media_store/`
- **Database**: `synapse_mx` (user: `synapse_mx`)
- **Port**: 8018 (Synapse) → 8082 (Nginx)

### User IDs

Users on this server have IDs like: `@username:mx.vish.gg`

### Federation

- ✅ Can communicate with matrix.org and other federated servers
- ✅ Can join public rooms on other servers
- ✅ Other users can find and message your users

### Managing the Service

```bash
sudo systemctl start synapse-mx
sudo systemctl stop synapse-mx
sudo systemctl restart synapse-mx
sudo systemctl status synapse-mx
```

Service file: `/etc/systemd/system/synapse-mx.service`

## Legacy Server: vish (matrix.thevish.io)

**This server contains historical data and cannot federate.**

### Why No Federation?

The `server_name` is `vish` which is not a valid domain. Other Matrix servers cannot discover it because:
- No DNS record for `vish`
- Cannot serve `.well-known` at `https://vish/`

### Configuration

- **Location**: `/opt/synapse/`
- **Config**: `/opt/synapse/homeserver.yaml`
- **Signing Key**: `/opt/synapse/vish.signing.key`
- **Media Store**: `/opt/synapse/media_store/`
- **Database**: `synapse` (user: `synapse`)
- **Port**: 8008 (Synapse) → 8081 (Nginx)

### User IDs

Users on this server have IDs like: `@username:vish`

### Managing the Service

```bash
sudo systemctl start synapse
sudo systemctl stop synapse
sudo systemctl restart synapse
sudo systemctl status synapse
```

Service file: `/etc/systemd/system/synapse.service`

## TURN Server (coturn)

TURN server enables voice/video calls to work through NAT.

### Configuration

- **Config**: `/etc/turnserver.conf`
- **Ports**: 3479 (TURN), 5350 (TURNS), 49201-49250 (Media relay UDP)
- **Realm**: `matrix.thevish.io`
- **Auth Secret**: Shared with Synapse (`turn_shared_secret`)

### Key Settings

```ini
listening-port=3479
tls-listening-port=5350
listening-ip=0.0.0.0
external-ip=YOUR_WAN_IP/192.168.0.154
static-auth-secret=<shared-secret>
realm=matrix.thevish.io
min-port=49201
max-port=49250
```

### Port Forwarding Required

| Port | Protocol | Purpose |
|------|----------|---------|
| 3479 | TCP/UDP | TURN |
| 5350 | TCP/UDP | TURNS (TLS) |
| 49201-49250 | UDP | Media relay |

## Element Web

Element Web is served by Nginx for both instances.

### mx.vish.gg

- **Location**: `/opt/element/web/`
- **Config**: `/opt/element/web/config.json`
- **URL**: https://mx.vish.gg/

### matrix.thevish.io

- **Location**: `/opt/element/web-thevish/`
- **Config**: `/opt/element/web-thevish/config.json`
- **URL**: https://matrix.thevish.io/

## Nginx Configuration

### mx.vish.gg (port 8082)

Location: `/etc/nginx/sites-available/mx-vish-gg`

```nginx
server {
    listen 8082;
    server_name mx.vish.gg;
    root /opt/element/web;

    location /health { proxy_pass http://127.0.0.1:8018; }
    location ~ ^(/_matrix|/_synapse/client) { proxy_pass http://127.0.0.1:8018; }
    location /_matrix/federation { proxy_pass http://127.0.0.1:8018; }
    location /.well-known/matrix/server { return 200 '{"m.server": "mx.vish.gg:443"}'; }
    location /.well-known/matrix/client { return 200 '{"m.homeserver": {"base_url": "https://mx.vish.gg"}}'; }
    location / { try_files $uri $uri/ /index.html; }
}
```

### matrix.thevish.io (port 8081)

Location: `/etc/nginx/sites-available/matrix-thevish`

```nginx
server {
    listen 8081;
    server_name matrix.thevish.io;
    root /opt/element/web-thevish;

    location /health { proxy_pass http://127.0.0.1:8008; }
    location ~ ^(/_matrix|/_synapse/client) { proxy_pass http://127.0.0.1:8008; }
    location /.well-known/matrix/server { return 200 '{"m.server": "matrix.thevish.io:443"}'; }
    location /.well-known/matrix/client { return 200 '{"m.homeserver": {"base_url": "https://matrix.thevish.io"}}'; }
    location / { try_files $uri $uri/ /index.html; }
}
```

## Synology Reverse Proxy

| Name | Source (HTTPS) | Destination (HTTP) |
|------|----------------|-------------------|
| mx_vish_gg | mx.vish.gg:443 | 192.168.0.154:8082 |
| matrix_thevish | matrix.thevish.io:443 | 192.168.0.154:8081 |

## Cloudflare DNS

| Type | Name | Content | Proxy |
|------|------|---------|-------|
| A | mx.vish.gg | YOUR_WAN_IP | ✅ Proxied |
| A | matrix.thevish.io | YOUR_WAN_IP | ✅ Proxied |

## Database Backup

### Backup mx.vish.gg

```bash
sudo -u postgres pg_dump -Fc synapse_mx > synapse_mx_backup_$(date +%Y%m%d).dump
```

### Backup legacy vish

```bash
sudo -u postgres pg_dump -Fc synapse > synapse_vish_backup_$(date +%Y%m%d).dump
```

### Restore

```bash
sudo -u postgres pg_restore -d <database_name> <backup_file.dump>
```

## Testing Federation

Use the Matrix Federation Tester:

```bash
curl -s "https://federationtester.matrix.org/api/report?server_name=mx.vish.gg" | python3 -c "
import sys, json
d = json.load(sys.stdin)
print(f'Federation OK: {d.get(\"FederationOK\", False)}')
"
```

## Creating Users

### Via registration (if enabled)

Go to https://mx.vish.gg and click "Create account"

### Via command line

```bash
cd /opt/synapse-mx
sudo -u synapse /opt/synapse/venv/bin/register_new_matrix_user \
  -c /opt/synapse-mx/homeserver.yaml \
  -u <username> -p <password> -a
```

## Troubleshooting

### Check if Synapse is running

```bash
sudo systemctl status synapse synapse-mx
curl -s http://localhost:8008/_synapse/admin/v1/server_version  # legacy
curl -s http://localhost:8018/_synapse/admin/v1/server_version  # mx
```

### View logs

```bash
sudo journalctl -u synapse -f      # mx.vish.gg
sudo journalctl -u synapse-mx -f   # legacy vish
```

### Test health endpoints

```bash
curl http://localhost:8018/health  # mx.vish.gg
curl http://localhost:8008/health  # legacy vish
```

### Restart nginx

```bash
sudo nginx -t && sudo systemctl reload nginx
```

### DB ownership fix (apply if migrations fail on upgrade)

If Synapse fails to start after upgrade with `InsufficientPrivilege: must be owner of table`,
the DB tables need their ownership corrected. Run for the affected database:

```bash
# For synapse (legacy) DB:
sudo -u postgres psql synapse -t -c "
  SELECT 'ALTER TABLE public.' || tablename || ' OWNER TO synapse;'
  FROM pg_tables WHERE schemaname='public' AND tableowner <> 'synapse';
" | sudo -u postgres psql synapse

sudo -u postgres psql synapse -t -c "
  SELECT 'ALTER SEQUENCE ' || sequence_name || ' OWNER TO synapse;'
  FROM information_schema.sequences WHERE sequence_schema='public';
" | sudo -u postgres psql synapse

# For synapse_mx DB, replace 'synapse' with 'synapse_mx' throughout
```
