Sanitized mirror from private repository - 2026-04-20 01:32:01 UTC
Some checks failed
Documentation / Build Docusaurus (push) Failing after 5m3s
Documentation / Deploy to GitHub Pages (push) Has been skipped

This commit is contained in:
Gitea Mirror Bot
2026-04-20 01:32:01 +00:00
commit e7652c8dab
1445 changed files with 364095 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Vish
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,197 @@
# Matrix Synapse + Element Web Bare-Metal Installation
Production-ready Matrix homeserver with Element Web client for Ubuntu 24.04 LTS.
## Features
- **Synapse** - Matrix homeserver with PostgreSQL backend
- **Element Web** - Modern web client (v1.12.8)
- **Coturn** - TURN server for voice/video calls
- **Federation** - Connect with other Matrix servers
- **Nginx** - Reverse proxy for HTTP traffic
- **Auto-validation** - YAML config validation during install
## Quick Install
```bash
# On a fresh Ubuntu 24.04 VM (run as root)
export DOMAIN="mx.example.com"
export ADMIN_USER="admin"
curl -sSL https://git.vish.gg/Vish/matrix-element/raw/branch/main/install-baremetal.sh | bash
```
### One-Liner (with defaults)
```bash
curl -sSL https://git.vish.gg/Vish/matrix-element/raw/branch/main/install-baremetal.sh | DOMAIN=mx.example.com bash
```
## Requirements
- Ubuntu 24.04 LTS
- 2+ CPU cores
- 4GB+ RAM
- 50GB+ disk space
- Domain with DNS pointing to your server
## Post-Installation
### 1. Configure Reverse Proxy
If using a reverse proxy (Synology, Cloudflare, etc.), point:
- `https://your-domain.com:443``http://server-ip:8080`
- Enable WebSocket support
### 2. Port Forwarding for TURN (Voice/Video Calls)
Forward these ports to your Matrix server:
| Port | Protocol | Purpose |
|------|----------|---------|
| 3479 | TCP/UDP | TURN |
| 5350 | TCP/UDP | TURNS (TLS) |
| 49201-49250 | UDP | Media relay |
### 3. Change Admin Password
Login at `https://your-domain.com` and change the default password immediately.
## Scripts
### Verify Installation
```bash
# Check health of all services
./verify-matrix.sh
```
This checks:
- All services (synapse, nginx, coturn, postgresql)
- Matrix Client and Federation APIs
- Well-known endpoints
- Element Web accessibility
- Database status
### Fix/Repair
```bash
# Diagnose and fix common issues
./fix-matrix.sh
```
This automatically fixes:
- YAML configuration errors in homeserver.yaml
- File ownership and permissions
- Stopped services
- Common configuration issues
### Backup
```bash
# Create a full backup
./backup-matrix.sh
# Or specify custom location
BACKUP_DIR=/mnt/backup ./backup-matrix.sh
```
Creates:
- PostgreSQL database dump
- Configuration files
- Media files
- Signing keys
- TURN configuration
### Update
```bash
# Update Synapse and Element to latest versions
./update-matrix.sh
```
This will:
1. Create a backup (optional)
2. Update Synapse via pip
3. Run database migrations
4. Download latest Element Web
5. Restart services
## Configuration Files
| File | Purpose |
|------|---------|
| `/opt/synapse/homeserver.yaml` | Main Synapse config |
| `/opt/synapse/*.signing.key` | Server signing key (CRITICAL - backup!) |
| `/opt/element/web/config.json` | Element Web config |
| `/etc/turnserver.conf` | TURN server config |
| `/etc/nginx/sites-available/matrix` | Nginx config |
| `/root/.matrix_secrets` | Passwords and secrets |
## Service Management
```bash
# Check status
systemctl status synapse nginx coturn
# Restart services
systemctl restart synapse
systemctl restart nginx
systemctl restart coturn
# View logs
journalctl -u synapse -f
journalctl -u coturn -f
```
## Federation Testing
Test federation status:
```bash
curl https://federationtester.matrix.org/api/report?server_name=your-domain.com
```
## Adding Users
```bash
# Create a new user
cd /opt/synapse
source venv/bin/activate
register_new_matrix_user -c homeserver.yaml http://localhost:8008
# Create admin user
register_new_matrix_user -c homeserver.yaml -a http://localhost:8008
```
## Troubleshooting
### Check if services are running
```bash
systemctl status synapse nginx coturn postgresql
```
### Test Matrix API locally
```bash
curl http://localhost:8008/_matrix/client/versions
```
### Test well-known endpoints
```bash
curl https://your-domain.com/.well-known/matrix/server
curl https://your-domain.com/.well-known/matrix/client
```
### Check Synapse logs
```bash
journalctl -u synapse -n 100
tail -f /opt/synapse/homeserver.log
```
## Security Notes
- Change the admin password immediately after installation
- Keep `/opt/synapse/*.signing.key` secure and backed up
- Consider enabling rate limiting in production
- Review `/opt/synapse/homeserver.yaml` for security settings
## License
MIT License

View File

@@ -0,0 +1,119 @@
#!/bin/bash
# =============================================================================
# Matrix Synapse Backup Script
# Creates a complete backup for migration
# =============================================================================
# Run as root
set -e
BACKUP_DIR="${BACKUP_DIR:-/opt/synapse/backups}"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_NAME="matrix_backup_${TIMESTAMP}"
BACKUP_PATH="${BACKUP_DIR}/${BACKUP_NAME}"
echo "=========================================="
echo "Matrix Synapse Backup Script"
echo "Backup location: ${BACKUP_PATH}"
echo "=========================================="
mkdir -p "${BACKUP_PATH}"
# 1. Backup PostgreSQL
echo "[1/5] Backing up PostgreSQL database..."
sudo -u postgres pg_dump -Fc synapse > "${BACKUP_PATH}/synapse.dump"
echo " Database: $(du -h ${BACKUP_PATH}/synapse.dump | cut -f1)"
# 2. Backup Synapse config and keys
echo "[2/5] Backing up configuration..."
cp /opt/synapse/homeserver.yaml "${BACKUP_PATH}/"
cp /opt/synapse/*.signing.key "${BACKUP_PATH}/" 2>/dev/null || true
cp /opt/synapse/*.log.config "${BACKUP_PATH}/" 2>/dev/null || true
cp /root/.matrix_secrets "${BACKUP_PATH}/" 2>/dev/null || true
# 3. Backup media
echo "[3/5] Backing up media files (this may take a while)..."
if [ -d /opt/synapse/media_store ]; then
tar -czf "${BACKUP_PATH}/media_store.tar.gz" -C /opt/synapse media_store
echo " Media: $(du -h ${BACKUP_PATH}/media_store.tar.gz | cut -f1)"
else
echo " No media directory found"
fi
# 4. Backup Element config
echo "[4/5] Backing up Element config..."
cp /opt/element/web/config.json "${BACKUP_PATH}/element_config.json" 2>/dev/null || true
# 5. Backup TURN config
echo "[5/5] Backing up TURN config..."
cp /etc/turnserver.conf "${BACKUP_PATH}/" 2>/dev/null || true
# Create restore instructions
cat > "${BACKUP_PATH}/RESTORE.md" << 'RESTORE'
# Matrix Restore Instructions
## On the new server:
1. Run the install script first (it will create a fresh install)
2. Stop services:
```
systemctl stop synapse nginx coturn
```
3. Restore database:
```
sudo -u postgres dropdb synapse
sudo -u postgres createdb -O synapse -E UTF8 -l C -T template0 synapse
sudo -u postgres pg_restore -d synapse synapse.dump
```
4. Restore config files:
```
cp homeserver.yaml /opt/synapse/
cp *.signing.key /opt/synapse/
cp *.log.config /opt/synapse/
chown -R synapse:synapse /opt/synapse
```
5. Restore media:
```
cd /opt/synapse
tar -xzf /path/to/backup/media_store.tar.gz
chown -R synapse:synapse media_store
```
6. Restore TURN config:
```
cp turnserver.conf /etc/turnserver.conf
```
7. Restore Element config:
```
cp element_config.json /opt/element/web/config.json
```
8. Start services:
```
systemctl start coturn nginx synapse
```
RESTORE
# Create archive
echo ""
echo "Creating final archive..."
cd "${BACKUP_DIR}"
tar -czf "${BACKUP_NAME}.tar.gz" "${BACKUP_NAME}"
rm -rf "${BACKUP_NAME}"
FINAL_SIZE=$(du -h "${BACKUP_DIR}/${BACKUP_NAME}.tar.gz" | cut -f1)
echo ""
echo "=========================================="
echo "✅ Backup Complete!"
echo "=========================================="
echo ""
echo "Backup file: ${BACKUP_DIR}/${BACKUP_NAME}.tar.gz"
echo "Size: ${FINAL_SIZE}"
echo ""
echo "Download: scp root@server:${BACKUP_DIR}/${BACKUP_NAME}.tar.gz ."

196
deployments/matrix/fix-matrix.sh Executable file
View File

@@ -0,0 +1,196 @@
#!/bin/bash
# =============================================================================
# Matrix Synapse Fix/Repair Script
# Diagnoses and fixes common issues
# =============================================================================
# Run as root
echo "=========================================="
echo "Matrix Synapse Fix/Repair Tool"
echo "=========================================="
# Check root
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root"
exit 1
fi
FIXED=0
ERRORS=0
# 1. Check and fix YAML configuration
echo ""
echo "[1/6] Checking Synapse configuration..."
if [ -f /opt/synapse/homeserver.yaml ]; then
if python3 -c "import yaml; yaml.safe_load(open('/opt/synapse/homeserver.yaml'))" 2>/dev/null; then
echo " ✓ homeserver.yaml is valid YAML"
else
echo " ✗ homeserver.yaml has YAML errors!"
echo " Creating backup at /opt/synapse/homeserver.yaml.broken"
cp /opt/synapse/homeserver.yaml /opt/synapse/homeserver.yaml.broken
# Try to fix common issues
echo " Attempting automatic fix..."
# Remove duplicate keys and fix indentation issues
python3 << 'PYFIX'
import yaml
import re
try:
with open('/opt/synapse/homeserver.yaml', 'r') as f:
content = f.read()
# Try to parse and re-write
# First, try to fix common issues
lines = content.split('\n')
fixed_lines = []
in_list = False
for line in lines:
# Skip empty turn_uris followed by list items not indented under it
if line.strip() == 'turn_uris:':
in_list = True
fixed_lines.append(line)
elif in_list and line.strip().startswith('- "turn:'):
fixed_lines.append(' ' + line.strip())
elif in_list and line.strip().startswith('- "turns:'):
fixed_lines.append(' ' + line.strip())
elif in_list and not line.strip().startswith('-') and line.strip():
in_list = False
fixed_lines.append(line)
else:
fixed_lines.append(line)
fixed_content = '\n'.join(fixed_lines)
# Validate the fix
yaml.safe_load(fixed_content)
with open('/opt/synapse/homeserver.yaml', 'w') as f:
f.write(fixed_content)
print(" ✓ Configuration fixed automatically")
except Exception as e:
print(f" ✗ Auto-fix failed: {e}")
print(" Please manually fix /opt/synapse/homeserver.yaml")
print(" Backup saved at /opt/synapse/homeserver.yaml.broken")
PYFIX
FIXED=$((FIXED + 1))
fi
else
echo " ✗ homeserver.yaml not found!"
ERRORS=$((ERRORS + 1))
fi
# 2. Check file permissions
echo ""
echo "[2/6] Checking file permissions..."
if [ -d /opt/synapse ]; then
OWNER=$(stat -c '%U' /opt/synapse)
if [ "$OWNER" = "synapse" ]; then
echo " ✓ /opt/synapse owned by synapse user"
else
echo " ✗ Fixing ownership of /opt/synapse..."
chown -R synapse:synapse /opt/synapse
FIXED=$((FIXED + 1))
fi
# Check config file permissions
if [ -f /opt/synapse/homeserver.yaml ]; then
PERMS=$(stat -c '%a' /opt/synapse/homeserver.yaml)
if [ "$PERMS" = "600" ] || [ "$PERMS" = "640" ]; then
echo " ✓ homeserver.yaml has correct permissions"
else
echo " ✗ Fixing homeserver.yaml permissions..."
chmod 600 /opt/synapse/homeserver.yaml
FIXED=$((FIXED + 1))
fi
fi
fi
# 3. Check services
echo ""
echo "[3/6] Checking services..."
for svc in postgresql synapse nginx coturn; do
if systemctl is-active --quiet $svc 2>/dev/null; then
echo "$svc is running"
else
echo "$svc is not running, attempting to start..."
systemctl start $svc 2>/dev/null
sleep 2
if systemctl is-active --quiet $svc; then
echo "$svc started successfully"
FIXED=$((FIXED + 1))
else
echo " ✗ Failed to start $svc"
echo " Check logs: journalctl -u $svc -n 50"
ERRORS=$((ERRORS + 1))
fi
fi
done
# 4. Check database connection
echo ""
echo "[4/6] Checking database..."
if sudo -u postgres psql -c "SELECT 1" synapse > /dev/null 2>&1; then
echo " ✓ PostgreSQL connection successful"
else
echo " ✗ Cannot connect to synapse database"
ERRORS=$((ERRORS + 1))
fi
# 5. Check nginx configuration
echo ""
echo "[5/6] Checking nginx configuration..."
if nginx -t 2>/dev/null; then
echo " ✓ Nginx configuration is valid"
else
echo " ✗ Nginx configuration has errors"
nginx -t
ERRORS=$((ERRORS + 1))
fi
# 6. Check API endpoints
echo ""
echo "[6/6] Checking API endpoints..."
sleep 1
if curl -sf http://localhost:8008/_matrix/client/versions > /dev/null 2>&1; then
echo " ✓ Matrix Client API responding"
else
echo " ✗ Matrix Client API not responding"
echo " Checking Synapse logs..."
journalctl -u synapse -n 10 --no-pager 2>/dev/null | tail -5
ERRORS=$((ERRORS + 1))
fi
LISTEN_PORT=$(grep -oP '^ listen \K\d+' /etc/nginx/sites-enabled/matrix 2>/dev/null | head -1 || echo "8080")
if curl -sf http://localhost:$LISTEN_PORT/ > /dev/null 2>&1; then
echo " ✓ Element Web accessible on port $LISTEN_PORT"
else
echo " ✗ Element Web not accessible"
ERRORS=$((ERRORS + 1))
fi
# Summary
echo ""
echo "=========================================="
if [ $ERRORS -eq 0 ]; then
if [ $FIXED -eq 0 ]; then
echo "✅ All checks passed! No issues found."
else
echo "✅ Fixed $FIXED issue(s). All checks now pass."
echo ""
echo "You may want to restart services:"
echo " systemctl restart synapse nginx"
fi
else
echo "⚠️ Found $ERRORS error(s) that need manual attention."
echo ""
echo "Common fixes:"
echo " - Check logs: journalctl -u synapse -f"
echo " - Validate YAML: python3 -c \"import yaml; yaml.safe_load(open('/opt/synapse/homeserver.yaml'))\""
echo " - Restart services: systemctl restart postgresql synapse nginx coturn"
fi
echo "=========================================="
exit $ERRORS

View File

@@ -0,0 +1,377 @@
#!/bin/bash
# =============================================================================
# Matrix Synapse + Element Web Bare-Metal Install Script
# For Ubuntu 24.04 LTS
# =============================================================================
# Usage:
# export DOMAIN="mx.example.com"
# export ADMIN_USER="admin"
# export ADMIN_EMAIL="admin@example.com"
# curl -sSL https://git.vish.gg/Vish/matrix-element/raw/branch/main/install-baremetal.sh | bash
#
# Run as root on a fresh Ubuntu 24.04 VM
# =============================================================================
set -e
# Configuration
DOMAIN="${DOMAIN:-mx.example.com}"
ADMIN_USER="${ADMIN_USER:-admin}"
ADMIN_EMAIL="${ADMIN_EMAIL:-admin@example.com}"
TURN_DOMAIN="${TURN_DOMAIN:-$DOMAIN}"
TURN_PORT="${TURN_PORT:-3479}"
TURN_TLS_PORT="${TURN_TLS_PORT:-5350}"
TURN_MIN_PORT="${TURN_MIN_PORT:-49201}"
TURN_MAX_PORT="${TURN_MAX_PORT:-49250}"
ELEMENT_VERSION="${ELEMENT_VERSION:-v1.12.8}"
LISTEN_PORT="${LISTEN_PORT:-8080}"
echo "=========================================="
echo "Matrix Synapse + Element Web Installer"
echo "=========================================="
echo "Domain: $DOMAIN"
echo "Admin: $ADMIN_USER"
echo "=========================================="
# Check root
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root"
exit 1
fi
# Update system
echo "[1/10] Updating system..."
apt update && apt upgrade -y
# Install dependencies
echo "[2/10] Installing dependencies..."
apt install -y postgresql postgresql-contrib nginx coturn \
python3-pip python3-venv python3-dev build-essential \
libffi-dev libssl-dev libjpeg-dev libxslt1-dev \
curl wget git jq
# Create synapse user
echo "[3/10] Creating synapse user..."
useradd -r -m -d /opt/synapse -s /bin/bash synapse 2>/dev/null || true
mkdir -p /opt/synapse /opt/element
chown synapse:synapse /opt/synapse
# Setup PostgreSQL
echo "[4/10] Setting up PostgreSQL..."
DB_PASS="REDACTED_PASSWORD" rand -hex 16)
sudo -u postgres psql -c "CREATE USER synapse WITH PASSWORD 'REDACTED_PASSWORD';" 2>/dev/null || \
sudo -u postgres psql -c "ALTER USER synapse WITH PASSWORD 'REDACTED_PASSWORD';"
sudo -u postgres psql -c "CREATE DATABASE synapse ENCODING 'UTF8' LC_COLLATE='C' LC_CTYPE='C' template=template0 OWNER synapse;" 2>/dev/null || true
# Install Synapse
echo "[5/10] Installing Synapse..."
sudo -u synapse bash << SYNAPSE_INSTALL
cd /opt/synapse
python3 -m venv venv
source venv/bin/activate
pip install --upgrade pip setuptools wheel
pip install matrix-synapse psycopg2-binary lxml 'prometheus-client<0.21'
SYNAPSE_INSTALL
# Generate config
echo "[6/10] Generating Synapse configuration..."
cd /opt/synapse
sudo -u synapse /opt/synapse/venv/bin/python -m synapse.app.homeserver \
--server-name "$DOMAIN" \
--config-path homeserver.yaml \
--generate-config \
--report-stats=no
# Get generated secrets
REG_SECRET=$(grep 'registration_shared_secret' homeserver.yaml | head -1 | awk '{print $2}')
MAC_SECRET=$(grep 'macaroon_secret_key' homeserver.yaml | head -1 | awk '{print $2}')
FORM_SECRET=$(grep 'form_secret' homeserver.yaml | head -1 | awk '{print $2}')
TURN_SECRET=$(openssl rand -hex 32)
# Create production config
cat > /opt/synapse/homeserver.yaml << YAML
server_name: "$DOMAIN"
pid_file: /opt/synapse/homeserver.pid
public_baseurl: https://$DOMAIN/
listeners:
- port: 8008
tls: false
type: http
x_forwarded: true
resources:
- names: [client, federation]
compress: false
database:
name: psycopg2
args:
user: synapse
password: "REDACTED_PASSWORD"
database: synapse
host: localhost
cp_min: 5
cp_max: 10
log_config: "/opt/synapse/$DOMAIN.log.config"
media_store_path: /opt/synapse/media_store
signing_key_path: "/opt/synapse/$DOMAIN.signing.key"
trusted_key_servers:
- server_name: "matrix.org"
registration_shared_secret: $REG_SECRET
macaroon_secret_key: $MAC_SECRET
form_secret: $FORM_SECRET
enable_registration: false
enable_registration_without_verification: false
turn_uris:
- "turn:$TURN_DOMAIN:$TURN_PORT?transport=udp"
- "turn:$TURN_DOMAIN:$TURN_PORT?transport=tcp"
- "turns:$TURN_DOMAIN:$TURN_TLS_PORT?transport=udp"
- "turns:$TURN_DOMAIN:$TURN_TLS_PORT?transport=tcp"
turn_shared_secret: "$TURN_SECRET"
turn_user_lifetime: 86400000
turn_allow_guests: true
max_upload_size: 100M
url_preview_enabled: true
url_preview_ip_range_blacklist:
- '127.0.0.0/8'
- '10.0.0.0/8'
- '172.16.0.0/12'
- '192.168.0.0/16'
- '100.64.0.0/10'
- '169.254.0.0/16'
- '::1/128'
- 'fe80::/64'
- 'fc00::/7'
suppress_key_server_warning: true
enable_metrics: false
report_stats: false
YAML
# Validate YAML configuration
echo "Validating Synapse configuration..."
python3 -c "import yaml; yaml.safe_load(open('/opt/synapse/homeserver.yaml'))" || {
echo "ERROR: Invalid YAML in homeserver.yaml"
exit 1
}
mkdir -p /opt/synapse/media_store
chown -R synapse:synapse /opt/synapse
# Configure coturn
echo "[7/10] Configuring TURN server..."
cat > /etc/turnserver.conf << TURN
listening-port=$TURN_PORT
tls-listening-port=$TURN_TLS_PORT
fingerprint
use-auth-secret
static-auth-secret=$TURN_SECRET
realm=$DOMAIN
total-quota=100
bps-capacity=0
stale-nonce=600
no-multicast-peers
min-port=$TURN_MIN_PORT
max-port=$TURN_MAX_PORT
log-file=/var/log/turnserver.log
TURN
# Download Element Web
echo "[8/10] Installing Element Web..."
cd /opt/element
wget -q "https://github.com/element-hq/element-web/releases/download/$ELEMENT_VERSION/element-$ELEMENT_VERSION.tar.gz"
tar xzf "element-$ELEMENT_VERSION.tar.gz"
mv "element-$ELEMENT_VERSION" web
rm "element-$ELEMENT_VERSION.tar.gz"
cat > /opt/element/web/config.json << ELEMENT
{
"default_server_config": {
"m.homeserver": {
"base_url": "https://$DOMAIN",
"server_name": "$DOMAIN"
}
},
"disable_guests": true,
"default_theme": "dark",
"room_directory": {
"servers": ["matrix.org", "$DOMAIN"]
}
}
ELEMENT
# Configure nginx
echo "[9/10] Configuring nginx..."
cat > /etc/nginx/sites-available/matrix << NGINX
server {
listen $LISTEN_PORT;
listen [::]:$LISTEN_PORT;
server_name $DOMAIN;
root /opt/element/web;
index index.html;
location ~ ^(/_matrix|/_synapse/client) {
proxy_pass http://127.0.0.1:8008;
proxy_set_header X-Forwarded-For \$remote_addr;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_set_header Host \$host;
client_max_body_size 100M;
proxy_http_version 1.1;
}
location /_matrix/federation {
proxy_pass http://127.0.0.1:8008;
proxy_set_header X-Forwarded-For \$remote_addr;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_set_header Host \$host;
client_max_body_size 100M;
}
location /.well-known/matrix/server {
default_type application/json;
return 200 '{"m.server": "$DOMAIN:443"}';
}
location /.well-known/matrix/client {
default_type application/json;
add_header Access-Control-Allow-Origin *;
return 200 '{"m.homeserver": {"base_url": "https://$DOMAIN"}}';
}
location / {
try_files \$uri \$uri/ /index.html;
}
}
NGINX
ln -sf /etc/nginx/sites-available/matrix /etc/nginx/sites-enabled/matrix
rm -f /etc/nginx/sites-enabled/default
nginx -t
# Create systemd service
cat > /etc/systemd/system/synapse.service << SERVICE
[Unit]
Description=Synapse Matrix Homeserver
After=network.target postgresql.service
[Service]
Type=notify
User=synapse
Group=synapse
WorkingDirectory=/opt/synapse
ExecStart=/opt/synapse/venv/bin/python -m synapse.app.homeserver --config-path=/opt/synapse/homeserver.yaml
ExecReload=/bin/kill -HUP \$MAINPID
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
SERVICE
# Start services
echo "[10/10] Starting services..."
systemctl daemon-reload
systemctl enable --now postgresql nginx coturn synapse
# Create admin user
sleep 3
ADMIN_PASS="REDACTED_PASSWORD" rand -hex 12)
cd /opt/synapse
sudo -u synapse /opt/synapse/venv/bin/register_new_matrix_user \
-c homeserver.yaml \
-u "$ADMIN_USER" \
-p "$ADMIN_PASS" \
-a \
http://localhost:8008
# Save secrets
cat > /root/.matrix_secrets << SECRETS
DOMAIN=$DOMAIN
DB_PASS="REDACTED_PASSWORD"
TURN_SECRET=$TURN_SECRET
ADMIN_USER=$ADMIN_USER
ADMIN_PASS="REDACTED_PASSWORD"
SECRETS
chmod 600 /root/.matrix_secrets
# Download helper scripts
echo "Downloading helper scripts..."
REPO_BASE="https://git.vish.gg/Vish/matrix-element/raw/branch/main"
mkdir -p /opt/matrix-scripts
for script in verify-matrix.sh fix-matrix.sh backup-matrix.sh update-matrix.sh; do
curl -sSL "$REPO_BASE/$script" -o "/opt/matrix-scripts/$script" 2>/dev/null || true
chmod +x "/opt/matrix-scripts/$script" 2>/dev/null || true
done
echo "Helper scripts installed to /opt/matrix-scripts/"
# Verify installation
echo ""
echo "Verifying installation..."
sleep 2
VERIFY_FAILED=0
# Check services
for svc in synapse nginx coturn postgresql; do
if systemctl is-active --quiet $svc; then
echo "$svc is running"
else
echo "$svc is NOT running"
VERIFY_FAILED=1
fi
done
# Check Matrix API
if curl -sf http://localhost:8008/_matrix/client/versions > /dev/null; then
echo "✓ Matrix API responding"
else
echo "✗ Matrix API not responding"
VERIFY_FAILED=1
fi
# Check Element Web
if curl -sf http://localhost:$LISTEN_PORT/ > /dev/null; then
echo "✓ Element Web accessible"
else
echo "✗ Element Web not accessible"
VERIFY_FAILED=1
fi
echo ""
echo "=========================================="
if [ $VERIFY_FAILED -eq 0 ]; then
echo "✅ Matrix Installation Complete!"
else
echo "⚠️ Installation complete with warnings"
fi
echo "=========================================="
echo ""
echo "Domain: $DOMAIN"
echo "Admin User: @$ADMIN_USER:$DOMAIN"
echo "Admin Password: "REDACTED_PASSWORD"
echo ""
echo "Listening on port $LISTEN_PORT (HTTP)"
echo ""
echo "Next steps:"
echo "1. Configure reverse proxy: HTTPS:443 → HTTP:$LISTEN_PORT"
echo "2. Forward TURN ports: $TURN_PORT, $TURN_TLS_PORT, $TURN_MIN_PORT-$TURN_MAX_PORT"
echo "3. Login at https://$DOMAIN and change password"
echo ""
echo "Secrets saved to /root/.matrix_secrets"
echo ""
echo "Helper scripts installed to /opt/matrix-scripts/"
echo " ./verify-matrix.sh - Check installation health"
echo " ./fix-matrix.sh - Diagnose and fix issues"
echo " ./backup-matrix.sh - Create full backup"
echo " ./update-matrix.sh - Update Synapse and Element"
echo ""
echo "Useful commands:"
echo " systemctl status synapse nginx coturn"
echo " journalctl -u synapse -f"
echo " curl http://localhost:8008/_matrix/client/versions"

View File

@@ -0,0 +1,103 @@
#!/bin/bash
# =============================================================================
# Matrix Synapse + Element Web Update Script
# =============================================================================
# Run as root
set -e
echo "=========================================="
echo "Matrix Synapse + Element Update Script"
echo "=========================================="
# Check current versions
CURRENT_SYNAPSE=$(/opt/synapse/venv/bin/python -c "import synapse; print(synapse.__version__)" 2>/dev/null || echo "unknown")
CURRENT_ELEMENT=$(cat /opt/element/web/version 2>/dev/null || ls /opt/element/ | grep -oP 'v[\d.]+' | head -1 || echo "unknown")
echo "Current Synapse: $CURRENT_SYNAPSE"
echo "Current Element: $CURRENT_ELEMENT"
# Get latest versions
echo ""
echo "Checking for updates..."
LATEST_ELEMENT=$(curl -s https://api.github.com/repos/element-hq/element-web/releases/latest | jq -r '.tag_name')
echo "Latest Element: $LATEST_ELEMENT"
read -p "Proceed with update? (y/N) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "Update cancelled."
exit 0
fi
# Backup first
echo ""
echo "[1/4] Creating backup..."
if [ -f ./backup-matrix.sh ]; then
./backup-matrix.sh
elif [ -f /opt/matrix-scripts/backup-matrix.sh ]; then
/opt/matrix-scripts/backup-matrix.sh
else
echo "Backup script not found, skipping..."
fi
# Update Synapse
echo ""
echo "[2/4] Updating Synapse..."
systemctl stop synapse
cd /opt/synapse
sudo -u synapse bash << 'UPDATE_SYNAPSE'
source venv/bin/activate
pip install --upgrade matrix-synapse psycopg2-binary lxml 'prometheus-client<0.21'
UPDATE_SYNAPSE
# Run database migrations
echo ""
echo "[3/4] Running database migrations..."
sudo -u synapse /opt/synapse/venv/bin/python -m synapse.app.homeserver \
--config-path /opt/synapse/homeserver.yaml \
--generate-keys-if-missing
# Update Element Web
echo ""
echo "[4/4] Updating Element Web..."
cd /opt/element
if [ -n "$LATEST_ELEMENT" ] && [ "$LATEST_ELEMENT" != "null" ]; then
# Backup old config
cp web/config.json /tmp/element_config_backup.json
# Download new version
wget -q "https://github.com/element-hq/element-web/releases/download/$LATEST_ELEMENT/element-$LATEST_ELEMENT.tar.gz"
# Remove old, extract new
rm -rf web
tar xzf "element-$LATEST_ELEMENT.tar.gz"
mv "element-$LATEST_ELEMENT" web
rm "element-$LATEST_ELEMENT.tar.gz"
# Restore config
cp /tmp/element_config_backup.json web/config.json
echo "Element updated to $LATEST_ELEMENT"
else
echo "Could not determine latest Element version, skipping Element update"
fi
# Start services
echo ""
echo "Starting services..."
systemctl start synapse
systemctl restart nginx
# Verify
sleep 3
NEW_SYNAPSE=$(/opt/synapse/venv/bin/python -c "import synapse; print(synapse.__version__)" 2>/dev/null || echo "unknown")
echo ""
echo "=========================================="
echo "✅ Update Complete!"
echo "=========================================="
echo ""
echo "Synapse: $CURRENT_SYNAPSE$NEW_SYNAPSE"
echo "Element: $CURRENT_ELEMENT$LATEST_ELEMENT"
echo ""
echo "Please verify your instance is working correctly."

View File

@@ -0,0 +1,126 @@
#!/bin/bash
# =============================================================================
# Matrix Synapse + Element Web Verification Script
# =============================================================================
# Run as root or with sudo
echo "=========================================="
echo "Matrix/Element Health Check"
echo "=========================================="
echo ""
FAILED=0
WARN=0
# Load domain from secrets if available
if [ -f /root/.matrix_secrets ]; then
source /root/.matrix_secrets
echo "Domain: ${DOMAIN:-unknown}"
fi
echo ""
echo "[Service Status]"
for svc in synapse nginx coturn postgresql; do
STATUS=$(systemctl is-active $svc 2>/dev/null || echo "not-found")
if [ "$STATUS" = "active" ]; then
echo "$svc: running"
elif [ "$STATUS" = "not-found" ]; then
echo " - $svc: not installed"
else
echo "$svc: $STATUS"
FAILED=1
fi
done
echo ""
echo "[Matrix API]"
# Client API
if curl -sf http://localhost:8008/_matrix/client/versions > /dev/null 2>&1; then
VERSION_COUNT=$(curl -s http://localhost:8008/_matrix/client/versions | python3 -c "import sys,json; print(len(json.load(sys.stdin).get('versions',[])))" 2>/dev/null || echo "0")
echo " ✓ Client API: responding ($VERSION_COUNT protocol versions)"
else
echo " ✗ Client API: not responding"
FAILED=1
fi
# Federation API
FED_RESULT=$(curl -sf http://localhost:8008/_matrix/federation/v1/version 2>/dev/null)
if [ -n "$FED_RESULT" ]; then
SYNAPSE_VER=$(echo "$FED_RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('server',{}).get('version','unknown'))" 2>/dev/null)
echo " ✓ Federation API: responding (Synapse $SYNAPSE_VER)"
else
echo " ✗ Federation API: not responding"
FAILED=1
fi
echo ""
echo "[Well-Known Endpoints]"
# Check nginx port
LISTEN_PORT=$(grep -oP 'listen \K\d+' /etc/nginx/sites-enabled/matrix 2>/dev/null | head -1 || echo "8080")
SERVER_WK=$(curl -sf http://localhost:$LISTEN_PORT/.well-known/matrix/server 2>/dev/null)
if [ -n "$SERVER_WK" ]; then
echo " ✓ /.well-known/matrix/server: $SERVER_WK"
else
echo " ✗ /.well-known/matrix/server: not configured"
WARN=1
fi
CLIENT_WK=$(curl -sf http://localhost:$LISTEN_PORT/.well-known/matrix/client 2>/dev/null)
if [ -n "$CLIENT_WK" ]; then
echo " ✓ /.well-known/matrix/client: configured"
else
echo " ✗ /.well-known/matrix/client: not configured"
WARN=1
fi
echo ""
echo "[Element Web]"
if curl -sf http://localhost:$LISTEN_PORT/ > /dev/null 2>&1; then
echo " ✓ Element Web: accessible on port $LISTEN_PORT"
else
echo " ✗ Element Web: not accessible"
FAILED=1
fi
# Check Element config
if [ -f /opt/element/web/config.json ]; then
HOMESERVER=$(python3 -c "import json; print(json.load(open('/opt/element/web/config.json')).get('default_server_config',{}).get('m.homeserver',{}).get('base_url','not set'))" 2>/dev/null)
echo " ✓ Element config: homeserver=$HOMESERVER"
else
echo " ✗ Element config: /opt/element/web/config.json not found"
WARN=1
fi
echo ""
echo "[TURN Server]"
if systemctl is-active --quiet coturn; then
TURN_PORT=$(grep -oP '^listening-port=\K\d+' /etc/turnserver.conf 2>/dev/null | head -1 || echo "3479")
echo " ✓ Coturn: running on port $TURN_PORT"
else
echo " - Coturn: not running (voice/video calls may not work behind NAT)"
WARN=1
fi
echo ""
echo "[Database]"
if systemctl is-active --quiet postgresql; then
DB_SIZE=$(sudo -u postgres psql -t -c "SELECT pg_size_pretty(pg_database_size('synapse'));" 2>/dev/null | xargs)
echo " ✓ PostgreSQL: running (synapse db: ${DB_SIZE:-unknown})"
else
echo " ✗ PostgreSQL: not running"
FAILED=1
fi
echo ""
echo "=========================================="
if [ $FAILED -eq 0 ] && [ $WARN -eq 0 ]; then
echo "✅ All checks passed!"
elif [ $FAILED -eq 0 ]; then
echo "⚠️ Passed with warnings"
else
echo "❌ Some checks failed"
fi
echo "=========================================="
exit $FAILED