feat(ess-pro/compose): deploy Element Server Suite Pro via Compose
initial commit of the converted role from helm charts for qubernetis to compose ansible role
This commit is contained in:
parent
c11f019aae
commit
32eca6b923
33 changed files with 1906 additions and 0 deletions
9
roles/ess_pro_compose/templates/haproxy/429.http.j2
Normal file
9
roles/ess_pro_compose/templates/haproxy/429.http.j2
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
HTTP/1.0 429 Too Many Requests
|
||||
Cache-Control: no-cache
|
||||
Connection: close
|
||||
Content-Type: application/json
|
||||
access-control-allow-origin: *
|
||||
access-control-allow-methods: GET, POST, PUT, DELETE, OPTIONS
|
||||
access-control-allow-headers: Origin, X-Requested-With, Content-Type, Accept, Authorization
|
||||
|
||||
{"errcode":"M_UNKNOWN","error":"Server is unavailable"}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
# {{ ansible_managed }}
|
||||
{% for cidr in ess_admin_allow_ips %}
|
||||
{{ cidr }}
|
||||
{% endfor %}
|
||||
177
roles/ess_pro_compose/templates/haproxy/haproxy.cfg.j2
Normal file
177
roles/ess_pro_compose/templates/haproxy/haproxy.cfg.j2
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
# {{ ansible_managed }}
|
||||
# Adapted from ess-helm chart {{ ess_chart_version }} (ess-haproxy ConfigMap).
|
||||
# K8s DNS-SRV-based service discovery replaced with direct compose hostnames.
|
||||
|
||||
global
|
||||
maxconn 20000
|
||||
log stdout format raw local0 info
|
||||
tune.maxrewrite 4096
|
||||
stats socket ipv4@127.0.0.1:1999 level admin
|
||||
dns-accept-family ipv4
|
||||
|
||||
defaults
|
||||
mode http
|
||||
fullconn 10000
|
||||
maxconn 10000
|
||||
log global
|
||||
option forwardfor if-none
|
||||
option forwarded
|
||||
timeout connect 5s
|
||||
timeout queue 60s
|
||||
timeout client 900s
|
||||
timeout http-keep-alive 900s
|
||||
timeout http-request 10s
|
||||
timeout server 180s
|
||||
http-reuse aggressive
|
||||
default-server maxconn 500
|
||||
option redispatch
|
||||
compression algo gzip
|
||||
compression type text/plain text/html text/xml application/json text/css
|
||||
hash-type consistent sdbm
|
||||
|
||||
# Compose resolves service names via the embedded DNS (127.0.0.11). We point
|
||||
# HAProxy at it so backend health-checks pick up restarts properly.
|
||||
resolvers compose-dns
|
||||
nameserver dns1 127.0.0.11:53
|
||||
accepted_payload_size 8192
|
||||
hold timeout 600s
|
||||
hold refused 600s
|
||||
|
||||
frontend prometheus
|
||||
bind *:8405
|
||||
http-request use-service prometheus-exporter if { path /metrics }
|
||||
monitor-uri /haproxy_test
|
||||
no log
|
||||
|
||||
frontend http-blackhole
|
||||
bind *:8009
|
||||
http-request deny content-type application/json string '{"errcode": "M_FORBIDDEN", "error": "Blocked"}'
|
||||
|
||||
frontend startup
|
||||
bind *:8406
|
||||
acl synapse_dead nbsrv(synapse-main) lt 1
|
||||
monitor-uri /synapse_ready
|
||||
monitor fail if synapse_dead
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Synapse traffic — main entrypoint that the DMZ Traefik points at for matrix.*
|
||||
# ----------------------------------------------------------------------------
|
||||
frontend synapse-http-in
|
||||
bind *:8008
|
||||
errorfile 503 /synapse/429.http
|
||||
http-request capture hdr(host) len 32
|
||||
http-request capture req.fhdr(x-forwarded-for) len 64
|
||||
http-request capture req.fhdr(user-agent) len 200
|
||||
|
||||
http-request set-header X-Forwarded-Proto https if !{ hdr(X-Forwarded-Proto) -m found }
|
||||
http-request set-var(txn.x_forwarded_proto) hdr(x-forwarded-proto)
|
||||
http-response add-header Strict-Transport-Security max-age=31536000 if { var(txn.x_forwarded_proto) -m str -i "https" }
|
||||
|
||||
# Access token extraction (used by upstream rate-limit decisions)
|
||||
http-request set-var(req.access_token) urlp("access_token") if { urlp("access_token") -m found }
|
||||
http-request set-var(req.access_token) req.fhdr(Authorization),word(2," ") if { hdr_beg("Authorization") -i "Bearer " }
|
||||
http-request set-header X-Access-Token %[var(req.access_token)]
|
||||
|
||||
http-response set-header Permissions-Policy "interest-cohort=()"
|
||||
|
||||
# Admin endpoint IP allow-list
|
||||
acl is_admin path_reg ^/_synapse/admin/.*
|
||||
http-request set-var(txn.user_ip) req.fhdr(x-forwarded-for) if { hdr(x-forwarded-for) -m found }
|
||||
http-request set-var(txn.user_ip) src if !{ hdr(x-forwarded-for) -m found }
|
||||
acl allow_ip_admin var(txn.user_ip) -m ip -f /synapse/admin-allow-ips.lst
|
||||
http-request deny if !allow_ip_admin is_admin
|
||||
|
||||
# FOSS-worker path maps (empty by default; reserved for advanced worker splits)
|
||||
acl has_get_map path -m reg -M -f /synapse/path_map_file_get
|
||||
http-request set-var(req.backend) path,map_reg(/synapse/path_map_file_get,main) if has_get_map METH_GET
|
||||
http-request set-var(req.backend) path,map_reg(/synapse/path_map_file,main) unless { var(req.backend) -m found }
|
||||
|
||||
# Pro federation-reader worker: takes /event, /state, /state_ids reads
|
||||
acl has_available_pro_fed nbsrv('synapse-pro-federation-api-requests') ge 1
|
||||
http-request set-var(req.backend) str('pro-federation-api-requests') if has_available_pro_fed { path -m reg ^/_matrix/federation/v1/event/ }
|
||||
http-request set-var(req.backend) str('pro-federation-api-requests') if has_available_pro_fed { path -m reg ^/_matrix/federation/v1/state/ }
|
||||
http-request set-var(req.backend) str('pro-federation-api-requests') if has_available_pro_fed { path -m reg ^/_matrix/federation/v1/state_ids/ }
|
||||
|
||||
# CORS preflight short-circuits
|
||||
acl rendezvous path_beg /_matrix/client/unstable/org.matrix.msc4108/rendezvous
|
||||
acl rendezvous path_beg /_synapse/client/rendezvous
|
||||
use_backend return_204_rendezvous if { method OPTIONS } rendezvous
|
||||
use_backend return_204_synapse if { method OPTIONS }
|
||||
|
||||
# Failover from pro-fed-reader to main if the worker is unavailable
|
||||
acl has_failover var(req.backend) -m str "pro-federation-api-requests"
|
||||
acl backend_unavailable str(),concat('synapse-',req.backend),nbsrv lt 1
|
||||
use_backend synapse-main-failover if has_failover backend_unavailable
|
||||
|
||||
use_backend synapse-%[var(req.backend)]
|
||||
|
||||
backend synapse-main
|
||||
default-server maxconn 250
|
||||
option httpchk
|
||||
http-check connect port 8080
|
||||
http-check send meth GET uri /health
|
||||
server main synapse-main:8008 check port 8080 resolvers compose-dns
|
||||
|
||||
backend synapse-main-failover
|
||||
default-server maxconn 250
|
||||
option httpchk
|
||||
http-check connect port 8080
|
||||
http-check send meth GET uri /health
|
||||
server main synapse-main:8008 check port 8080 resolvers compose-dns
|
||||
|
||||
backend synapse-pro-federation-api-requests
|
||||
option httpchk
|
||||
http-check connect port 8008
|
||||
http-check send meth GET uri /health/alive
|
||||
balance uri whole
|
||||
# The federation-reader worker is a Rust service speaking h2c.
|
||||
{% for i in range(ess_synapse_fed_reader_replicas | int) %}
|
||||
server fed-reader-{{ i }} synapse-fed-reader-{{ i }}:8008 check resolvers compose-dns proto h2
|
||||
{% endfor %}
|
||||
|
||||
backend return_204_synapse
|
||||
http-request return status 204 hdr "Access-Control-Allow-Origin" "*" hdr "Access-Control-Allow-Methods" "GET, HEAD, POST, PUT, DELETE, OPTIONS" hdr "Access-Control-Allow-Headers" "Origin, X-Requested-With, Content-Type, Accept, Authorization, Date" hdr "Access-Control-Expose-Headers" "Synapse-Trace-Id, Server"
|
||||
|
||||
backend return_204_rendezvous
|
||||
http-request return status 204 hdr "Access-Control-Allow-Origin" "*" hdr "Access-Control-Allow-Methods" "GET, HEAD, POST, PUT, DELETE, OPTIONS" hdr "Access-Control-Allow-Headers" "Origin, Content-Type, Accept, Content-Type, If-Match, If-None-Match" hdr "Access-Control-Expose-Headers" "Synapse-Trace-Id, Server, ETag"
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Well-known — served at the apex domain via the same HAProxy.
|
||||
# DMZ Traefik routes Host=`{{ ess_server_name }}` && PathPrefix(/.well-known) here.
|
||||
# ----------------------------------------------------------------------------
|
||||
frontend well-known-in
|
||||
bind *:8010
|
||||
acl is_delete_put_post_method method DELETE POST PUT
|
||||
http-request deny status 405 if is_delete_put_post_method
|
||||
|
||||
acl well-known path /.well-known/matrix/server
|
||||
acl well-known path /.well-known/matrix/client
|
||||
acl well-known path /.well-known/matrix/support
|
||||
acl well-known path /.well-known/element/element.json
|
||||
http-request redirect code 301 location https://{{ ess_hostnames.element_web }} unless well-known
|
||||
|
||||
use_backend well-known-static if well-known
|
||||
default_backend well-known-no-match
|
||||
|
||||
backend well-known-static
|
||||
mode http
|
||||
http-after-response set-header X-Frame-Options SAMEORIGIN
|
||||
http-after-response set-header X-Content-Type-Options nosniff
|
||||
http-after-response set-header X-XSS-Protection "1; mode=block"
|
||||
http-after-response set-header Content-Security-Policy "frame-ancestors 'self'"
|
||||
http-after-response set-header X-Robots-Tag "noindex, nofollow, noarchive, noimageindex"
|
||||
http-after-response set-header Access-Control-Allow-Origin *
|
||||
http-after-response set-header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
|
||||
http-after-response set-header Access-Control-Allow-Headers "X-Requested-With, Content-Type, Authorization"
|
||||
|
||||
http-request return status 200 content-type "application/json" file "/well-known/server" if { path /.well-known/matrix/server }
|
||||
http-request return status 200 content-type "application/json" file "/well-known/client" if { path /.well-known/matrix/client }
|
||||
http-request return status 200 content-type "application/json" file "/well-known/support" if { path /.well-known/matrix/support }
|
||||
http-request return status 200 content-type "application/json" file "/well-known/element.json" if { path /.well-known/element/element.json }
|
||||
|
||||
backend well-known-no-match
|
||||
mode http
|
||||
http-request deny status 404
|
||||
|
||||
backend return_500
|
||||
http-request deny deny_status 500
|
||||
5
roles/ess_pro_compose/templates/haproxy/path_map_file.j2
Normal file
5
roles/ess_pro_compose/templates/haproxy/path_map_file.j2
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# {{ ansible_managed }}
|
||||
# Map matrix paths to worker backends. Format: path_regexp backend_name
|
||||
# Chart default: empty (no FOSS-worker splits). Reserved for advanced
|
||||
# worker topologies; the Pro federation-reader routing is hard-coded in
|
||||
# haproxy.cfg via the synapse-pro-federation-api-requests backend.
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
# {{ ansible_managed }}
|
||||
# GET-only worker path map. See path_map_file for context.
|
||||
11
roles/ess_pro_compose/templates/haproxy/well-known/client.j2
Normal file
11
roles/ess_pro_compose/templates/haproxy/well-known/client.j2
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"m.homeserver": {
|
||||
"base_url": "https://{{ ess_hostnames.synapse }}"
|
||||
},
|
||||
"org.matrix.msc4143.rtc_foci": [
|
||||
{
|
||||
"livekit_service_url": "https://{{ ess_hostnames.matrix_rtc }}",
|
||||
"type": "livekit"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"m.server": "{{ ess_hostnames.synapse }}:443"}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
Loading…
Add table
Add a link
Reference in a new issue