job "continuwuity" { datacenters = ["dc1"] type = "service" node_pool = "default" group "continuwuity" { count = 1 network { port "http" { static = 6167 } } service { name = "continuwuity" port = "http" tags = [ "traefik.enable=true", # --- Homeserver (client + federation API) on cn.i80.dk --- "traefik.http.routers.continuwuity.rule=Host(`cn.i80.dk`)", "traefik.http.routers.continuwuity.entrypoints=https", "traefik.http.routers.continuwuity.tls=true", # No certresolver: Traefik serves the *.i80.dk wildcard cert from /certs via SNI. # --- Delegation: server_name is i80.dk, so the apex must serve /.well-known/matrix/* --- # MXIDs become @user:i80.dk; federation/clients resolve i80.dk -> cn.i80.dk. "traefik.http.routers.continuwuity-wk.rule=Host(`i80.dk`) && PathPrefix(`/.well-known/matrix`)", "traefik.http.routers.continuwuity-wk.entrypoints=https", "traefik.http.routers.continuwuity-wk.tls=true", # Higher priority so it wins over any bare Host(`i80.dk`) website router. # NOTE: requires the cert to include i80.dk as a SAN (a *.i80.dk wildcard alone does NOT cover the apex). "traefik.http.routers.continuwuity-wk.priority=100", # --- http -> https redirect for both routers --- "traefik.http.routers.continuwuity-http.rule=Host(`cn.i80.dk`)", "traefik.http.routers.continuwuity-http.entrypoints=http", "traefik.http.routers.continuwuity-http.middlewares=continuwuity-redirect", "traefik.http.routers.continuwuity-wk-http.rule=Host(`i80.dk`) && PathPrefix(`/.well-known/matrix`)", "traefik.http.routers.continuwuity-wk-http.entrypoints=http", "traefik.http.routers.continuwuity-wk-http.middlewares=continuwuity-redirect", "traefik.http.routers.continuwuity-wk-http.priority=100", "traefik.http.middlewares.continuwuity-redirect.redirectscheme.scheme=https", "traefik.http.middlewares.continuwuity-redirect.redirectscheme.permanent=true", ] check { name = "continuwuity-http" type = "http" port = "http" path = "/_matrix/client/versions" interval = "30s" timeout = "5s" check_restart { limit = 3 grace = "60s" } } } volume "continuwuity-volume" { type = "csi" read_only = false source = "continuwuity-volume" attachment_mode = "file-system" access_mode = "single-node-writer" per_alloc = false } volume "continuwuity-media-volume" { type = "csi" read_only = false source = "continuwuity-media-volume" attachment_mode = "file-system" access_mode = "single-node-writer" per_alloc = false mount_options { mount_flags = [] } } restart { attempts = 3 interval = "10m" delay = "30s" mode = "delay" } update { max_parallel = 1 health_check = "checks" min_healthy_time = "30s" healthy_deadline = "5m" auto_revert = true } task "continuwuity" { driver = "docker" env { # server_name is PERMANENT — it is the suffix of every user/room ID (@henrik:i80.dk). CONTINUWUITY_SERVER_NAME = "i80.dk" CONTINUWUITY_TRUSTED_SERVERS = "[\"matrix.org\"]" CONTINUWUITY_ALLOW_REGISTRATION = false CONTINUWUITY_ADDRESS = "0.0.0.0" CONTINUWUITY_PORT = 6167 CONTINUWUITY_DATABASE_PATH = "/var/lib/continuwuity" # Delegation: the homeserver lives at cn.i80.dk, advertised via the apex .well-known. # client = base URL (no port); server = host:port for federation. CONTINUWUITY_WELL_KNOWN = <