folders on server:
caddy  cinny  coturn  docker-compose.yml  element-releases  grafana  mautrix-telegram  mautrix-telegram-config.yaml.go-backup  postgres  prometheus  sygnal  synapse

docker-compose.yml
services:
  postgres:
    image: postgres:16
    restart: unless-stopped
    environment:
      POSTGRES_USER: synapse
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: synapse
      POSTGRES_INITDB_ARGS: "--encoding=UTF8 --lc-collate=C --lc-ctype=C"
    volumes:
      - ./postgres:/var/lib/postgresql/data

  synapse:
    image: matrixdotorg/synapse:latest
    restart: unless-stopped
    depends_on:
      - postgres
    volumes:
      - ./synapse:/data
    ports:
      - "8008:8008"

  caddy:
    image: caddy:2
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "8448:8448"
    volumes:
      - ./caddy/Caddyfile:/etc/caddy/Caddyfile
      - ./caddy/data:/data
      - ./caddy/config:/config
      - ./cinny:/var/www/cinny

  prometheus:
    image: prom/prometheus:latest
    restart: unless-stopped
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
      - ./prometheus/data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.retention.time=30d'

  grafana:
    image: grafana/grafana:latest
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=
    volumes:
      - ./grafana:/var/lib/grafana

  coturn:
    image: coturn/coturn:latest
    restart: unless-stopped
    network_mode: host
    volumes:
      - ./coturn/turnserver.conf:/etc/coturn/turnserver.conf

  telegram-bridge:
      image: dock.mau.dev/mautrix/telegram:v0.15.3
      restart: unless-stopped
      volumes:
        - ./mautrix-telegram:/data

  sygnal:
      image: matrixdotorg/sygnal:latest
      restart: unless-stopped
      healthcheck:
        disable: true
      volumes:
            - ./sygnal/sygnal.yaml:/sygnal.yaml
            - ./sygnal/fcm-service-account.json:/fcm-service-account.json
            - ./sygnal/vapid_private_key:/vapid_private_key
      command: ["python", "-m", "sygnal", "-c", "/sygnal.yaml"]

caddy/Caddyfile
vojo.chat {
    handle /_matrix/* {
        reverse_proxy synapse:8008
    }
    handle /_synapse/* {
        reverse_proxy synapse:8008
    }
    handle /.well-known/matrix/server {
        respond `{"m.server": "vojo.chat:443"}`
        header Content-Type application/json
    }
    handle /.well-known/matrix/client {
        respond `{"m.homeserver": {"base_url": "https://vojo.chat"}, "io.element.e2ee": {"force_disable": true}}`
        header Content-Type application/json
        header Access-Control-Allow-Origin *
    }
    handle {
        root * /var/www/cinny
        @nocache path /config.json /index.html /manifest.json /sw.js
        header @nocache Cache-Control "no-cache, no-store, must-revalidate"
        try_files {path} /index.html
        file_server
    }
}

vojo.chat:8448 {
    reverse_proxy synapse:8008
}

synapse/homeserver.yaml
# Configuration file for Synapse.
#
# This is a YAML file: see [1] for a quick introduction. Note in particular
# that *indentation is important*: all the elements of a list or dictionary
# should have the same indentation.
#
# [1] https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html
#
# For more information on how to configure Synapse, including a complete accounting of
# each option, go to docs/usage/configuration/config_documentation.md or
# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html
server_name: "vojo.chat"
pid_file: /data/homeserver.pid
listeners:
  - port: 8008
    resources:
    - compress: false
      names:
      - client
      - federation
    tls: false
    type: http
    x_forwarded: true
  - port: 9000
    type: metrics
    bind_addresses: ['0.0.0.0']
database:
  name: psycopg2
  args:
    user: synapse
    password: DfgoeFDgr12
    database: synapse
    host: postgres
    cp_min: 5
    cp_max: 10
push:
  enabled: true
  include_content: true
log_config: "/data/vojo.chat.log.config"
media_store_path: /data/media_store
registration_shared_secret: ""
report_stats: false
macaroon_secret_key: ""
form_secret: ""
signing_key_path: "/data/vojo.chat.signing.key"
trusted_key_servers:
  - server_name: "matrix.org"
enable_registration: true
enable_registration_without_verification: true
enable_metrics: true
turn_uris:
  - "turn:vojo.chat:3478?transport=udp"
  - "turn:vojo.chat:3478?transport=tcp"
turn_shared_secret: ""
turn_user_lifetime: 86400000
turn_allow_guests: false
encryption_enabled_by_default_for_room_type: "off"
app_service_config_files:
  - /data/telegram-registration.yaml
federation_ip_range_whitelist:
  - '172.18.0.0/16'
ip_range_whitelist:
  - '172.18.0.0/16'