From dfcf157b597f962923f7db627fca942561ec08af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Lametti?=
Date: Wed, 4 Mar 2026 08:57:14 -0500 Subject: [PATCH 1/5] Declare tuwunel upstream in single block This is essentially a variable so it is more clear to use an `upstream` declaration in case the IP or port changes. --- docs/deploying/reverse-proxy-nginx.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/deploying/reverse-proxy-nginx.md b/docs/deploying/reverse-proxy-nginx.md index 53008e2b..83be9958 100644 --- a/docs/deploying/reverse-proxy-nginx.md +++ b/docs/deploying/reverse-proxy-nginx.md @@ -24,6 +24,10 @@ sudo pacman -S nginx Create a new configuration file at `/etc/nginx/sites-available/tuwunel` (or `/etc/nginx/conf.d/tuwunel.conf` on some distributions): ```nginx +upstream tuwunel { + 127.0.0.1:8008; # IP and port where tuwunel is listening +} + # Client-Server API over HTTPS (port 443) server { listen 443 ssl http2; @@ -34,9 +38,9 @@ server { # Increase this to match the max_request_size in your tuwunel.toml client_max_body_size 100M; - # Forward requests to Tuwunel (listening on 127.0.0.1:8008) + # Forward requests to Tuwunel location / { - proxy_pass http://127.0.0.1:8008; + proxy_pass http://tuwunel; # Preserve host and scheme - critical for proper Matrix operation proxy_set_header Host $host; @@ -62,7 +66,7 @@ server { # Forward to the same local port as client-server API location / { - proxy_pass http://127.0.0.1:8008; + proxy_pass http://tuwunel; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto https; @@ -103,7 +107,7 @@ However, if you experience federation retries or dropped long-poll connections, ```nginx location / { - proxy_pass http://127.0.0.1:8008; + proxy_pass http://tuwunel; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto https; From a023ca377193dd2968136b9ad9360f39ac9faf5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Lametti?=
Date: Wed, 4 Mar 2026 09:28:13 -0500 Subject: [PATCH 2/5] Fix typo in quote order --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index 4e82f5ca..894650d4 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -35,7 +35,7 @@ string. This does not apply to options that take booleans or numbers: - `-O max_request_size=99999999` works ✅ - `-O server_name=example.com` does not work ❌ - `--option log=\"debug\"` works ✅ -- `--option server_name='"example.com'"` works ✅ +- `--option server_name='"example.com"'` works ✅ ## Relevance of configuration settings From 0ee71890ed9c0fe0de9bf10fbb700b3c80d3e74c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Lametti?=
Date: Wed, 4 Mar 2026 10:58:12 -0500 Subject: [PATCH 3/5] Add missing docs index entry for podman --- docs/SUMMARY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 1093e03c..f4d26a86 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -15,6 +15,7 @@ - [Debian](deploying/debian.md) - [Red Hat](deploying/redhat.md) - [FreeBSD](deploying/freebsd.md) + - [Podman systemd](deploying/podman-systemd.md) - [TURN](turn.md) - [Matrix RTC (Element Call)](matrix_rtc.md) - [Appservices](appservices.md) From b81ef81a707eac3f975216b2d6a0b530b4630191 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Lametti?=
Date: Wed, 4 Mar 2026 13:33:08 -0500
Subject: [PATCH 4/5] Docs: add example for root domain delegation
Although the procedure is documented in the example configuration file,
whether it is possible to use the root domain as the server name of a
tuwunel instance hosted on a subdomain, and a practical example of doing
so, is often requested in the unofficial support matrix room.
TODO:
- [ ] Add example for Caddy
- [ ] Add example for Traefik
---
docs/SUMMARY.md | 1 +
docs/deploying/generic.md | 4 +-
docs/deploying/root-domain-delegation.md | 118 +++++++++++++++++++++++
3 files changed, 121 insertions(+), 2 deletions(-)
create mode 100644 docs/deploying/root-domain-delegation.md
diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md
index f4d26a86..c859ce1c 100644
--- a/docs/SUMMARY.md
+++ b/docs/SUMMARY.md
@@ -8,6 +8,7 @@
- [Reverse Proxy - Caddy](deploying/reverse-proxy-caddy.md)
- [Reverse Proxy - Nginx](deploying/reverse-proxy-nginx.md)
- [Reverse Proxy - Traefik](deploying/reverse-proxy-traefik.md)
+ - [Example: root domain delegation](deploying/root-domain-delegation.md)
- [NixOS](deploying/nixos.md)
- [Docker](deploying/docker.md)
- [Kubernetes](deploying/kubernetes.md)
diff --git a/docs/deploying/generic.md b/docs/deploying/generic.md
index c724b9fc..d2c56ce1 100644
--- a/docs/deploying/generic.md
+++ b/docs/deploying/generic.md
@@ -73,7 +73,7 @@ Matrix's default federation port is port 8448, and clients must be using port 44
If you would like to use only port 443, or a different port, you will need to setup
delegation. Tuwunel has config options for doing delegation, or you can configure
your reverse proxy to manually serve the necessary JSON files to do delegation
-(see the `[global.well_known]` config section).
+(see the `[global.well_known]` config section and the [delegation example](root-domain-delegation.md)).
If Tuwunel runs behind a router or in a container and has a different public
IP address than the host system these public ports need to be forwarded directly
@@ -158,7 +158,7 @@ Regardless of which reverse proxy you choose, you will need to:
- `/_tuwunel/` - ad-hoc Tuwunel routes such as `/local_user_count` and `/server_version`
2. **Optionally reverse proxy (recommended):**
- - `/.well-known/matrix/client` and `/.well-known/matrix/server` if using Tuwunel to perform delegation (see the `[global.well_known]` config section)
+ - `/.well-known/matrix/client` and `/.well-known/matrix/server` if using Tuwunel to perform delegation (see the `[global.well_known]` config section and the [delegation example](root-domain-delegation.md))
- `/.well-known/matrix/support` if using Tuwunel to send the homeserver admin contact and support page (formerly known as MSC1929)
- `/` if you would like to see `hewwo from tuwunel woof!` at the root
diff --git a/docs/deploying/root-domain-delegation.md b/docs/deploying/root-domain-delegation.md
new file mode 100644
index 00000000..3e2276a0
--- /dev/null
+++ b/docs/deploying/root-domain-delegation.md
@@ -0,0 +1,118 @@
+# Example: using the root domain as the homeserver name
+
+[<= Back to Generic Deployment Guide](generic.md#quick-overview)
+
+It is possible to host tuwunel on a subdomain such as `matrix.example.com` but delegate from `example.com` as the server name. This means that usernames will be `@user:example.com` rather than `@user:matrix.example.com`.
+
+Federating servers and clients accessing tuwunel at `example.com` will attempt to discover the subdomain by accessing the `example.com/.well-known/matrix/client` and `example.com/.well-known/matrix/server` endpoints. These need to be set up to point back to `matrix.example.com`.
+
+> [!NOTE]
+> In all of the following examples, replace `matrix.example.com` with the subdomain where tuwunel is hosted, `
Date: Wed, 4 Mar 2026 13:33:08 -0500
Subject: [PATCH 5/5] Docs: add example for root domain delegation
- Change link in README to internal documentation link; original more
detailed link is preserved in documentation page as a reference.
- Add Caddy example.
TODO:
- [x] Add example for Caddy
- [ ] Add example for Traefik
---
README.md | 2 +-
docs/deploying/root-domain-delegation.md | 25 +++++++++++++++++++++++-
2 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index d6139a5a..54dd31ac 100644
--- a/README.md
+++ b/README.md
@@ -51,7 +51,7 @@ This is just a summary for the impatient. See the full
[documentation](https://matrix-construct.github.io/tuwunel/).
> [!TIP]
-> Avoid using a sub-domain for your `server_name`. You can always delegate later with a [`.well-known`](https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/docs/configuring-well-known.md)
+> Avoid using a sub-domain for your `server_name`. You can always delegate later with a [`.well-known`](https://matrix-construct.github.io/tuwunel/deploying/root-domain-delegation.html)
> file, but you can never change your `server_name`.
**2.** Setup TLS certificates. Most users enjoy the [Caddy](https://caddyserver.com/) reverse-proxy
diff --git a/docs/deploying/root-domain-delegation.md b/docs/deploying/root-domain-delegation.md
index 3e2276a0..b2f60104 100644
--- a/docs/deploying/root-domain-delegation.md
+++ b/docs/deploying/root-domain-delegation.md
@@ -92,11 +92,28 @@ At a minimum, the following JSON files should be created:
### Option 2: Reverse proxy
-This is an example configuration if `example.com` is reverse-proxied behing Nginx.
+These are example configurations if `example.com` is reverse-proxied behing Nginx or Caddy.
> [!NOTE]
> Replace `tuwunel` with the URL where tuwunel is listening; this may look like `127.0.0.1:8008`, `matrix.example.com`, or `tuwunel` if you declared an `upstream tuwunel` block.
+> [!IMPORTANT]
+> These configurations need to be applied to the reverse proxy for `example.com`, **not** `matrix.example.com`.
+
+#### Caddy
+
+
+
+```caddy
+example.com {
+ reverse_proxy /.well-known/matrix/* https://matrix.example.com {
+ header_up Host {upstream_hostport}
+ }
+}
+```
+
+#### Nginx
+
```nginx,hidelines=~
server {
~listen 443 ssl http2;
@@ -116,3 +133,9 @@ server {
## Testing
Navigate to `example.com/.well-known/matrix/client` and `example.com/.well-known/matrix/server`. These should display results similar to the [JSON snippets above](#option-1-static-json-files).
+
+Entering `example.com` in the [Matrix federation tester](https://federationtester.matrix.org/) should also work.
+
+## Additional resources
+
+For a more complete guide, see the Matrix setup with Ansible and Docker [documentation on setting up `.well-known`](https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/docs/configuring-well-known.md).