diff options
| -rw-r--r-- | Makefile | 15 | ||||
| -rw-r--r-- | PKGBUILD | 15 | ||||
| -rw-r--r-- | README (renamed from readme.txt) | 0 | ||||
| -rw-r--r-- | whiterabbit.1 | 51 | ||||
| -rwxr-xr-x | whiterabbit.sh | 367 |
5 files changed, 286 insertions, 162 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fe1c42b --- /dev/null +++ b/Makefile | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | PREFIX ?= /usr/local | ||
| 2 | BINDIR ?= $(PREFIX)/bin | ||
| 3 | MANDIR ?= $(PREFIX)/share/man/man1 | ||
| 4 | |||
| 5 | install: | ||
| 6 | @echo "Installing whiterabbit..." | ||
| 7 | install -Dm755 whiterabbit.sh $(BINDIR)/whiterabbit | ||
| 8 | install -Dm644 whiterabbit.1 $(MANDIR)/whiterabbit.1 | ||
| 9 | @echo "Installed to $(BINDIR)/whiterabbit and man page to $(MANDIR)/whiterabbit.1" | ||
| 10 | |||
| 11 | uninstall: | ||
| 12 | @echo "Removing whiterabbit..." | ||
| 13 | rm -f $(BINDIR)/whiterabbit | ||
| 14 | rm -f $(MANDIR)/whiterabbit.1 | ||
| 15 | @echo "Removed whiterabbit and its man page" | ||
diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 0000000..c1cd771 --- /dev/null +++ b/PKGBUILD | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | pkgname=whiterabbit | ||
| 2 | pkgver=1.0.0 | ||
| 3 | pkgrel=1 | ||
| 4 | pkgdesc="Auto-configure Matrix homeservers (Dendrite/Synapse) with Coturn and Nginx/Let's Encrypt" | ||
| 5 | arch=('x86_64') | ||
| 6 | url="https://example.com/whiterabbit" | ||
| 7 | license=('MIT') | ||
| 8 | depends=('docker' 'docker-compose' 'nginx' 'certbot' 'coturn' 'bash') | ||
| 9 | source=("whiterabbit.sh") | ||
| 10 | sha256sums=('SKIP') | ||
| 11 | |||
| 12 | package() { | ||
| 13 | install -Dm755 "$srcdir/whiterabbit.sh" "$pkgdir/usr/bin/whiterabbit" | ||
| 14 | } | ||
| 15 | |||
diff --git a/whiterabbit.1 b/whiterabbit.1 new file mode 100644 index 0000000..e02030f --- /dev/null +++ b/whiterabbit.1 | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | .\" Manpage for whiterabbit | ||
| 2 | .TH WHITERABBIT 1 "2025-09-25" "1.0.0" "whiterabbit manual" | ||
| 3 | .SH NAME | ||
| 4 | whiterabbit \- auto-configure Matrix homeservers (Dendrite or Synapse) | ||
| 5 | .SH SYNOPSIS | ||
| 6 | .B whiterabbit | ||
| 7 | [\fIturn\fR|\fIdendrite\fR|\fIsynapse\fR|\fIlist\fR|\fIremove <domain>\fR] | ||
| 8 | .SH DESCRIPTION | ||
| 9 | whiterabbit sets up Matrix homeservers with a global Coturn server and Nginx/Let's Encrypt support. | ||
| 10 | |||
| 11 | Main commands: | ||
| 12 | .TP | ||
| 13 | .B turn | ||
| 14 | Install or configure the global Coturn server. | ||
| 15 | .TP | ||
| 16 | .B dendrite | ||
| 17 | Add a new Matrix Dendrite server. | ||
| 18 | .TP | ||
| 19 | .B synapse | ||
| 20 | Add a new Matrix Synapse server. | ||
| 21 | .TP | ||
| 22 | .B list | ||
| 23 | List all configured Matrix servers. | ||
| 24 | .TP | ||
| 25 | .B remove <domain> | ||
| 26 | Remove a Matrix server by domain. | ||
| 27 | |||
| 28 | .SH EXAMPLES | ||
| 29 | .TP | ||
| 30 | whiterabbit turn | ||
| 31 | Set up the global Coturn server. | ||
| 32 | .TP | ||
| 33 | whiterabbit dendrite | ||
| 34 | Add a Dendrite server with TLS and Nginx. | ||
| 35 | .TP | ||
| 36 | whiterabbit synapse | ||
| 37 | Add a Synapse server with TLS and Nginx. | ||
| 38 | .TP | ||
| 39 | whiterabbit list | ||
| 40 | Show all servers. | ||
| 41 | .TP | ||
| 42 | whiterabbit remove matrix.example.com | ||
| 43 | Remove a server. | ||
| 44 | |||
| 45 | .SH NOTES | ||
| 46 | All Matrix servers share the same Coturn instance. | ||
| 47 | TLS certificates are issued automatically via Let's Encrypt. | ||
| 48 | Requires docker, docker-compose, nginx, certbot, and coturn. | ||
| 49 | |||
| 50 | .SH AUTHOR | ||
| 51 | Filip Wandzio <contact@philw.dev> | ||
diff --git a/whiterabbit.sh b/whiterabbit.sh index e68351f..e6e3b58 100755 --- a/whiterabbit.sh +++ b/whiterabbit.sh | |||
| @@ -1,104 +1,185 @@ | |||
| 1 | #!/usr/bin/sh | 1 | #!/bin/sh |
| 2 | set -euo pipefail | 2 | set -eu |
| 3 | 3 | ||
| 4 | echo "=== Matrix Dendrite + Coturn auto-setup (Docker + standalone Coturn) ===" | 4 | BASE_DIR="/opt/matrix" |
| 5 | 5 | ||
| 6 | # ---- User Input ---- | 6 | usage() { |
| 7 | read -rp "Matrix domain (eg. matrix.example.com): " MATRIX_DOMAIN | 7 | cat <<'EOF' |
| 8 | read -rp "TURN domain(eg. turn.example.com): " TURN_DOMAIN | 8 | whiterabbit: auto-configure Matrix homeservers (Dendrite or Synapse) |
| 9 | read -rp "Let's Encrypt certificate email: " EMAIL | 9 | with a global Coturn instance and Nginx + Let's Encrypt proxy. |
| 10 | read -rp "Postgres secret: " DB_PASS | 10 | |
| 11 | read -rp "registration_shared_secret: " REG_SECRET | 11 | Main actions: |
| 12 | read -rp "TURN shared secret: " TURN_SECRET | 12 | turn Install or configure the global Coturn server |
| 13 | read -rp "TURN IP (eg. 127.0.0.1): " TURN_SERVER_IP | 13 | dendrite Add a new Matrix server (Dendrite) |
| 14 | read -rp "MATRIX server IP (eg. 127.0.0.1): " MATRIX_SERVER_IP | 14 | synapse Add a new Matrix server (Synapse) |
| 15 | read -rp "Listening device (eg. eth0): " TURN_LISTENING_DEVICE | 15 | list Show all configured Matrix servers |
| 16 | 16 | remove Remove a Matrix server by domain | |
| 17 | INSTALL_DIR="/opt/matrix/$MATRIX_DOMAIN" | 17 | |
| 18 | mkdir -p "$INSTALL_DIR/config" | 18 | Notes: |
| 19 | cd "$INSTALL_DIR" | 19 | • Coturn should be installed only once using 'turn'. |
| 20 | 20 | • All Matrix servers share the same Coturn (TURN domain/secret). | |
| 21 | cat <<EOF > .env | 21 | • TLS certificates are issued automatically using Let's Encrypt. |
| 22 | # PostgreSQL | 22 | • Requirements: docker, docker-compose, nginx, certbot, coturn. |
| 23 | |||
| 24 | EOF | ||
| 25 | exit 1 | ||
| 26 | } | ||
| 27 | |||
| 28 | list_servers() { | ||
| 29 | echo "=== Installed servers ===" | ||
| 30 | ls -1 "$BASE_DIR" 2>/dev/null || echo "No servers installed" | ||
| 31 | } | ||
| 32 | |||
| 33 | install_turn() { | ||
| 34 | echo "=== Installing global Coturn ===" | ||
| 35 | printf "TURN domain (eg. turn.example.com): " | ||
| 36 | read -r TURN_DOMAIN | ||
| 37 | printf "TURN IP (eg. 127.0.0.1): " | ||
| 38 | read -r TURN_SERVER_IP | ||
| 39 | printf "Listening device (eg. eth0): " | ||
| 40 | read -r TURN_LISTENING_DEVICE | ||
| 41 | printf "TURN shared secret: " | ||
| 42 | read -r TURN_SECRET | ||
| 43 | |||
| 44 | mkdir -p /etc/turn | ||
| 45 | cat <<EOF > /etc/turn/turnserver.conf | ||
| 46 | listening-device=$TURN_LISTENING_DEVICE | ||
| 47 | listening-port=3478 | ||
| 48 | tls-listening-port=5349 | ||
| 49 | listening-ip=$TURN_SERVER_IP | ||
| 50 | min-port=49152 | ||
| 51 | max-port=65535 | ||
| 52 | use-auth-secret | ||
| 53 | static-auth-secret=$TURN_SECRET | ||
| 54 | realm=$TURN_DOMAIN | ||
| 55 | syslog | ||
| 56 | no-rfc5780 | ||
| 57 | no-stun-backward-compatibility | ||
| 58 | response-origin-only-with-rfc5780 | ||
| 59 | EOF | ||
| 60 | |||
| 61 | echo "$TURN_DOMAIN" > /etc/turn/domain | ||
| 62 | echo "$TURN_SECRET" > /etc/turn/secret | ||
| 63 | |||
| 64 | systemctl enable --now coturn || true | ||
| 65 | echo "[OK] Global Coturn configured ($TURN_DOMAIN)" | ||
| 66 | } | ||
| 67 | |||
| 68 | common_prompts() { | ||
| 69 | printf "Matrix domain (eg. matrix.example.com): " | ||
| 70 | read -r MATRIX_DOMAIN | ||
| 71 | printf "Let's Encrypt certificate email: " | ||
| 72 | read -r EMAIL | ||
| 73 | printf "Postgres secret: " | ||
| 74 | read -r DB_PASS | ||
| 75 | printf "registration_shared_secret: " | ||
| 76 | read -r REG_SECRET | ||
| 77 | printf "MATRIX server IP (eg. 127.0.0.1): " | ||
| 78 | read -r MATRIX_SERVER_IP | ||
| 79 | |||
| 80 | TURN_DOMAIN=$(cat /etc/turn/domain) | ||
| 81 | TURN_SECRET=$(cat /etc/turn/secret) | ||
| 82 | } | ||
| 83 | |||
| 84 | configure_nginx() { | ||
| 85 | DOMAIN="$1" | ||
| 86 | SERVICE_PORT="$2" | ||
| 87 | |||
| 88 | cat <<EOF > "/etc/nginx/sites-available/$DOMAIN" | ||
| 89 | server { | ||
| 90 | listen 80; | ||
| 91 | server_name $DOMAIN; | ||
| 92 | |||
| 93 | location /.well-known/matrix/server { | ||
| 94 | default_type application/json; | ||
| 95 | return 200 '{ "m.server": "$DOMAIN:443" }'; | ||
| 96 | } | ||
| 97 | |||
| 98 | location /.well-known/matrix/client { | ||
| 99 | default_type application/json; | ||
| 100 | return 200 '{ | ||
| 101 | "m.homeserver": { "base_url": "https://$DOMAIN" }, | ||
| 102 | "m.identity_server": { "base_url": "https://vector.im" } | ||
| 103 | }'; | ||
| 104 | } | ||
| 105 | |||
| 106 | location / { | ||
| 107 | proxy_pass http://127.0.0.1:$SERVICE_PORT; | ||
| 108 | proxy_set_header Host \$host; | ||
| 109 | proxy_set_header X-Forwarded-For \$remote_addr; | ||
| 110 | } | ||
| 111 | } | ||
| 112 | EOF | ||
| 113 | |||
| 114 | ln -sf "/etc/nginx/sites-available/$DOMAIN" "/etc/nginx/sites-enabled/$DOMAIN" | ||
| 115 | nginx -t && systemctl reload nginx | ||
| 116 | |||
| 117 | certbot --nginx --non-interactive --agree-tos -m "$EMAIL" -d "$DOMAIN" | ||
| 118 | |||
| 119 | echo "[OK] Nginx and SSL certificate configured for $DOMAIN" | ||
| 120 | } | ||
| 121 | |||
| 122 | install_dendrite() { | ||
| 123 | echo "=== Installing Matrix Dendrite ===" | ||
| 124 | common_prompts | ||
| 125 | |||
| 126 | INSTALL_DIR="$BASE_DIR/$MATRIX_DOMAIN" | ||
| 127 | mkdir -p "$INSTALL_DIR/config" | ||
| 128 | cd "$INSTALL_DIR" || exit 1 | ||
| 129 | |||
| 130 | cat <<EOF > .env | ||
| 23 | POSTGRES_HOSTNAME=postgres | 131 | POSTGRES_HOSTNAME=postgres |
| 24 | POSTGRES_VERSION=15-alpine | 132 | POSTGRES_VERSION=15-alpine |
| 25 | POSTGRES_USER=dendrite | 133 | POSTGRES_USER=dendrite |
| 26 | POSTGRES_PASSWORD=$DB_PASS | 134 | POSTGRES_PASSWORD=$DB_PASS |
| 27 | POSTGRES_DB=dendrite | 135 | POSTGRES_DB=dendrite |
| 28 | 136 | ||
| 29 | # Monolith | ||
| 30 | MONOLITH_HOSTNAME=monolith | 137 | MONOLITH_HOSTNAME=monolith |
| 31 | MONOLITH_IMAGE=matrixdotorg/dendrite-monolith:latest | 138 | MONOLITH_IMAGE=matrixdotorg/dendrite-monolith:latest |
| 32 | MONOLITH_PORT_HTTP=8008 | 139 | MONOLITH_PORT_HTTP=8008 |
| 33 | MONOLITH_PORT_HTTPS=8448 | 140 | MONOLITH_PORT_HTTPS=8448 |
| 34 | EOF | 141 | EOF |
| 35 | 142 | ||
| 36 | cat <<'EOF' > compose.yml | 143 | cat <<'EOF' > compose.yml |
| 37 | services: | 144 | services: |
| 38 | postgres: | 145 | postgres: |
| 39 | hostname: ${POSTGRES_HOSTNAME:-postgres} | ||
| 40 | image: postgres:${POSTGRES_VERSION:-15-alpine} | 146 | image: postgres:${POSTGRES_VERSION:-15-alpine} |
| 41 | restart: always | 147 | restart: always |
| 42 | volumes: | 148 | volumes: |
| 43 | - ./dendrite_postgres_data:/var/lib/postgresql/data | 149 | - ./dendrite_postgres_data:/var/lib/postgresql/data |
| 44 | environment: | 150 | environment: |
| 45 | POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-itsasecret} | 151 | POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} |
| 46 | POSTGRES_USER: ${POSTGRES_USER:-dendrite} | 152 | POSTGRES_USER: ${POSTGRES_USER} |
| 47 | POSTGRES_DB: ${POSTGRES_DB:-dendrite} | 153 | POSTGRES_DB: ${POSTGRES_DB} |
| 48 | healthcheck: | 154 | networks: [ internal ] |
| 49 | test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-dendrite}"] | ||
| 50 | interval: 5s | ||
| 51 | timeout: 5s | ||
| 52 | retries: 5 | ||
| 53 | networks: | ||
| 54 | - internal | ||
| 55 | monolith: | 155 | monolith: |
| 56 | hostname: ${MONOLITH_HOSTNAME:-monolith} | 156 | image: ${MONOLITH_IMAGE} |
| 57 | image: ${MONOLITH_IMAGE:-matrixdotorg/dendrite-monolith:latest} | ||
| 58 | ports: | 157 | ports: |
| 59 | - ${MONOLITH_PORT_HTTP:-8008}:8008 | 158 | - ${MONOLITH_PORT_HTTP}:8008 |
| 60 | - ${MONOLITH_PORT_HTTPS:-8448}:8448 | 159 | - ${MONOLITH_PORT_HTTPS}:8448 |
| 61 | volumes: | 160 | volumes: |
| 62 | - ./config:/etc/dendrite | 161 | - ./config:/etc/dendrite |
| 63 | - ./dendrite_media:/var/dendrite/media | 162 | - ./dendrite_media:/var/dendrite/media |
| 64 | - ./dendrite_jetstream:/var/dendrite/jetstream | 163 | depends_on: [ postgres ] |
| 65 | - ./dendrite_search_index:/var/dendrite/searchindex | 164 | networks: [ internal ] |
| 66 | - ./:/mnt | ||
| 67 | depends_on: | ||
| 68 | postgres: | ||
| 69 | condition: service_healthy | ||
| 70 | networks: | ||
| 71 | - internal | ||
| 72 | restart: unless-stopped | 165 | restart: unless-stopped |
| 73 | networks: | 166 | networks: |
| 74 | internal: | 167 | internal: |
| 75 | attachable: true | 168 | attachable: true |
| 76 | volumes: | ||
| 77 | dendrite_postgres_data: | ||
| 78 | dendrite_media: | ||
| 79 | dendrite_jetstream: | ||
| 80 | dendrite_search_index: | ||
| 81 | EOF | 169 | EOF |
| 82 | 170 | ||
| 83 | cat <<EOF > config/dendrite.yaml | 171 | cat <<EOF > config/dendrite.yaml |
| 84 | version: 2 | 172 | version: 2 |
| 85 | global: | 173 | global: |
| 86 | server_name: $MATRIX_DOMAIN | 174 | server_name: $MATRIX_DOMAIN |
| 87 | private_key: /mnt/matrix_key.pem | 175 | private_key: /mnt/matrix_key.pem |
| 88 | old_private_keys: | ||
| 89 | key_validity_period: 168h0m0s | ||
| 90 | database: | 176 | database: |
| 91 | connection_string: postgresql://dendrite:$DB_PASS@postgres/dendrite?sslmode=disable | 177 | connection_string: postgresql://dendrite:$DB_PASS@postgres/dendrite?sslmode=disable |
| 92 | max_open_conns: 90 | ||
| 93 | max_idle_conns: 5 | ||
| 94 | conn_max_lifetime: -1 | ||
| 95 | |||
| 96 | well_known_server_name: "$MATRIX_DOMAIN:443" | 178 | well_known_server_name: "$MATRIX_DOMAIN:443" |
| 97 | well_known_client_name: "https://$MATRIX_DOMAIN" | 179 | well_known_client_name: "https://$MATRIX_DOMAIN" |
| 98 | 180 | ||
| 99 | client_api: | 181 | client_api: |
| 100 | registration_disabled: true | 182 | registration_disabled: true |
| 101 | guests_disabled: true | ||
| 102 | registration_shared_secret: "$REG_SECRET" | 183 | registration_shared_secret: "$REG_SECRET" |
| 103 | 184 | ||
| 104 | turn: | 185 | turn: |
| @@ -107,118 +188,80 @@ client_api: | |||
| 107 | - turn:$TURN_DOMAIN?transport=udp | 188 | - turn:$TURN_DOMAIN?transport=udp |
| 108 | - turn:$TURN_DOMAIN?transport=tcp | 189 | - turn:$TURN_DOMAIN?transport=tcp |
| 109 | turn_shared_secret: "$TURN_SECRET" | 190 | turn_shared_secret: "$TURN_SECRET" |
| 110 | |||
| 111 | federation_api: | ||
| 112 | send_max_retries: 16 | ||
| 113 | disable_tls_validation: false | ||
| 114 | |||
| 115 | media_api: | ||
| 116 | base_path: ./media_store | ||
| 117 | max_file_size_bytes: 10485760 | ||
| 118 | dynamic_thumbnails: false | ||
| 119 | thumbnail_sizes: | ||
| 120 | - width: 96 | ||
| 121 | height: 96 | ||
| 122 | method: crop | ||
| 123 | - width: 640 | ||
| 124 | height: 480 | ||
| 125 | method: scale | ||
| 126 | |||
| 127 | user_api: | ||
| 128 | bcrypt_cost: 10 | ||
| 129 | auto_join_rooms: | ||
| 130 | - "#main:$MATRIX_DOMAIN" | ||
| 131 | |||
| 132 | logging: | ||
| 133 | - type: std | ||
| 134 | level: info | ||
| 135 | EOF | 191 | EOF |
| 136 | 192 | ||
| 137 | cat <<EOF > /etc/turnserver.conf | 193 | docker compose up -d |
| 138 | listening-device=$TURN_LISTENING_DEVICE | ||
| 139 | listening-port=3478 | ||
| 140 | tls-listening-port=5349 | ||
| 141 | listening-ip=$TURN_SERVER_IP | ||
| 142 | min-port=49152 | ||
| 143 | max-port=65535 | ||
| 144 | use-auth-secret | ||
| 145 | static-auth-secret=$TURN_SECRET | ||
| 146 | syslog | ||
| 147 | no-rfc5780 | ||
| 148 | no-stun-backward-compatibility | ||
| 149 | response-origin-only-with-rfc5780 | ||
| 150 | EOF | ||
| 151 | 194 | ||
| 152 | echo "[INFO] Generating server keys..." | 195 | configure_nginx "$MATRIX_DOMAIN" "8008" |
| 153 | docker run --rm --entrypoint="" -v $(pwd):/mnt matrixdotorg/dendrite-monolith:latest /usr/bin/generate-keys -private-key /mnt/matrix_key.pem -tls-cert /mnt/server.crt -tls-key /mnt/server.key | ||
| 154 | 196 | ||
| 155 | echo "[INFO] Booting up containers(HTTP-only test)..." | 197 | echo "[OK] Dendrite server ($MATRIX_DOMAIN) is running." |
| 156 | docker compose up -d | 198 | } |
| 157 | 199 | ||
| 158 | echo "[INFO] Waiting for dendrite monolith to answer..." | 200 | install_synapse() { |
| 159 | for i in {1..30}; do | 201 | echo "=== Installing Matrix Synapse ===" |
| 160 | if curl -fs "http://$MATRIX_SERVER_IP:8008/_matrix/client/versions" >/dev/null 2>&1; then | 202 | common_prompts |
| 161 | echo "[OK] Monolith działa na http://$MATRIX_SERVER_IP:8008" | ||
| 162 | break | ||
| 163 | fi | ||
| 164 | echo " ...retry $i" | ||
| 165 | sleep 5 | ||
| 166 | done | ||
| 167 | 203 | ||
| 168 | echo "[INFO] Setting up NGINX RevPrx files" | 204 | INSTALL_DIR="$BASE_DIR/$MATRIX_DOMAIN" |
| 169 | cat <<EOF > /etc/nginx/sites-available/$MATRIX_DOMAIN | 205 | mkdir -p "$INSTALL_DIR" |
| 170 | server { | 206 | cd "$INSTALL_DIR" || exit 1 |
| 171 | listen 80; | ||
| 172 | listen [::]:80; | ||
| 173 | server_name $MATRIX_DOMAIN; | ||
| 174 | location /.well-known/matrix/client { | ||
| 175 | return 301 https://$host$request_uri; | ||
| 176 | } | ||
| 177 | location /.well-known/matrix/server { | ||
| 178 | return 301 https://$host$request_uri; | ||
| 179 | } | ||
| 180 | location / { | ||
| 181 | return 301 https://$host$request_uri; | ||
| 182 | } | ||
| 183 | } | ||
| 184 | 207 | ||
| 185 | server { | 208 | cat <<EOF > docker-compose.yml |
| 186 | listen 443 ssl http2; | 209 | version: '3.4' |
| 187 | listen [::]:443 ssl http2; | 210 | services: |
| 188 | server_name $MATRIX_DOMAIN; | 211 | db: |
| 212 | image: postgres:15-alpine | ||
| 213 | environment: | ||
| 214 | POSTGRES_USER: synapse | ||
| 215 | POSTGRES_PASSWORD: $DB_PASS | ||
| 216 | POSTGRES_DB: synapse | ||
| 217 | volumes: | ||
| 218 | - ./db:/var/lib/postgresql/data | ||
| 189 | 219 | ||
| 190 | ssl_certificate /etc/letsencrypt/live/$MATRIX_DOMAIN/fullchain.pem; | 220 | synapse: |
| 191 | ssl_certificate_key /etc/letsencrypt/live/$MATRIX_DOMAIN/privkey.pem; | 221 | image: matrixdotorg/synapse:latest |
| 192 | include /etc/letsencrypt/options-ssl-nginx.conf; | 222 | depends_on: [ db ] |
| 193 | ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; | 223 | environment: |
| 224 | SYNAPSE_SERVER_NAME: $MATRIX_DOMAIN | ||
| 225 | SYNAPSE_REPORT_STATS: "yes" | ||
| 226 | POSTGRES_PASSWORD: $DB_PASS | ||
| 227 | ports: | ||
| 228 | - 8008:8008 | ||
| 229 | - 8448:8448 | ||
| 230 | volumes: | ||
| 231 | - ./data:/data | ||
| 232 | EOF | ||
| 194 | 233 | ||
| 195 | location / { | 234 | docker compose up -d |
| 196 | proxy_pass http://127.0.0.1:8008; | ||
| 197 | proxy_http_version 1.1; | ||
| 198 | proxy_set_header Host $host; | ||
| 199 | proxy_set_header X-Real-IP $remote_addr; | ||
| 200 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||
| 201 | proxy_set_header X-Forwarded-Proto $scheme; | ||
| 202 | proxy_set_header Upgrade $http_upgrade; | ||
| 203 | proxy_set_header Connection "upgrade"; | ||
| 204 | } | ||
| 205 | 235 | ||
| 206 | location /.well-known/matrix/client { | 236 | cat <<EOF > data/homeserver-extra.yaml |
| 207 | default_type application/json; | 237 | turn_uris: [ "turn:$TURN_DOMAIN?transport=udp", "turn:$TURN_DOMAIN?transport=tcp" ] |
| 208 | add_header Access-Control-Allow-Origin *; | 238 | turn_shared_secret: "$TURN_SECRET" |
| 209 | return 200 '{"m.homeserver": {"base_url": "https://$MATRIX_DOMAIN"}}'; | 239 | turn_user_lifetime: "5m" |
| 210 | } | 240 | EOF |
| 211 | 241 | ||
| 212 | location /.well-known/matrix/server { | 242 | configure_nginx "$MATRIX_DOMAIN" "8008" |
| 213 | default_type application/json; | 243 | |
| 214 | add_header Access-Control-Allow-Origin *; | 244 | echo "[OK] Synapse server ($MATRIX_DOMAIN) is running." |
| 215 | return 200 '{"m.server": "$MATRIX_DOMAIN:443"}'; | ||
| 216 | } | ||
| 217 | } | 245 | } |
| 218 | EOF | ||
| 219 | 246 | ||
| 220 | ln -s /etc/nginx/sites-available/$MATRIX_DOMAIN | 247 | remove_server() { |
| 221 | echo "============================================" | 248 | DOMAIN="$1" |
| 222 | echo " Matrix server setup finished!" | 249 | [ -z "$DOMAIN" ] && usage |
| 223 | echo " HomeServer: https://$MATRIX_DOMAIN:8448" | 250 | SERVER_DIR="$BASE_DIR/$DOMAIN" |
| 224 | echo " TURN: $TURN_DOMAIN (3478/5349)" | 251 | rm -rf "$SERVER_DIR" |
| 252 | rm -f "/etc/nginx/sites-available/$DOMAIN" "/etc/nginx/sites-enabled/$DOMAIN" | ||
| 253 | nginx -t && systemctl reload nginx | ||
| 254 | echo "[OK] Server $DOMAIN removed." | ||
| 255 | } | ||
| 256 | |||
| 257 | # --- CLI router --- | ||
| 258 | CMD="${1:-}" | ||
| 259 | |||
| 260 | case "$CMD" in | ||
| 261 | turn) install_turn ;; | ||
| 262 | dendrite) install_dendrite ;; | ||
| 263 | synapse) install_synapse ;; | ||
| 264 | list) list_servers ;; | ||
| 265 | remove) remove_server "${2:-}" ;; | ||
| 266 | *) usage ;; | ||
| 267 | esac | ||
