From 493087050476aff3cb86763d741b170ea3a002e5 Mon Sep 17 00:00:00 2001 From: Elio Bischof Date: Thu, 7 Aug 2025 18:58:18 +0200 Subject: [PATCH] docs(login v2): update proxy examples (#10358) # Which Problems Are Solved - The proxy examples are updated so a self-hosted login container is deployed. - The proxies are configured to direct traffic at /ui/v2/login to it. # How the Problems Are Solved The base compose file is extended by correctly configured login containers for all three scenarios - TLS disabled - External TLS - TLS Enabled The proxy always connects to the login via HTTP. # Additional Changes - All proxies have the TLS disabled mode outcommented, because the login container has state problems, maybe because it needs secure cookies. The need for this is unclear, so we avoid creating a follow-up issue. - The httpd external mode is incommented, as gRPC connections work with this configuration. - *ZITADEL* is replaced by *Zitadel* # Additional Context - Partially Closes #10016 --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com> --- docs/docs/self-hosting/deploy/.gitignore | 2 +- docs/docs/self-hosting/manage/.gitignore | 3 + .../manage/reverseproxy/_caddy.mdx | 25 ---- .../manage/reverseproxy/_proxy_guide_more.mdx | 4 +- .../reverseproxy/_proxy_guide_overview.mdx | 4 +- .../reverseproxy/_proxy_guide_tls_mode.mdx | 20 +-- .../manage/reverseproxy/caddy/caddy.mdx | 4 +- .../reverseproxy/caddy/disabled-tls.Caddyfile | 1 + .../reverseproxy/caddy/docker-compose.yaml | 9 +- .../reverseproxy/caddy/enabled-tls.Caddyfile | 1 + .../reverseproxy/caddy/external-tls.Caddyfile | 1 + .../reverseproxy/cloudflare/cloudflare.mdx | 4 +- .../cloudflare_tunnel/cloudflare_tunnel.mdx | 2 +- .../manage/reverseproxy/docker-compose.yaml | 126 +++++++++++------- .../reverseproxy/httpd/docker-compose.yaml | 12 +- .../httpd/httpd-disabled-tls.conf | 15 ++- .../reverseproxy/httpd/httpd-enabled-tls.conf | 34 ++++- .../httpd/httpd-external-tls.conf | 26 +++- .../manage/reverseproxy/httpd/httpd.mdx | 9 +- .../reverseproxy/nginx/docker-compose.yaml | 9 +- .../nginx/nginx-disabled-tls.conf | 4 + .../reverseproxy/nginx/nginx-enabled-tls.conf | 5 + .../nginx/nginx-external-tls.conf | 6 + .../manage/reverseproxy/nginx/nginx.mdx | 4 +- .../manage/reverseproxy/reverse_proxy.mdx | 5 +- .../reverseproxy/traefik/docker-compose.yaml | 9 +- .../traefik/traefik-disabled-tls.yaml | 15 ++- .../traefik/traefik-enabled-tls.yaml | 19 ++- .../traefik/traefik-external-tls.yaml | 16 ++- .../manage/reverseproxy/traefik/traefik.mdx | 4 +- .../zitadel_cloud/zitadel_cloud.mdx | 16 +-- docs/sidebars.js | 1 + 32 files changed, 270 insertions(+), 145 deletions(-) create mode 100644 docs/docs/self-hosting/manage/.gitignore delete mode 100644 docs/docs/self-hosting/manage/reverseproxy/_caddy.mdx diff --git a/docs/docs/self-hosting/deploy/.gitignore b/docs/docs/self-hosting/deploy/.gitignore index aba9338c1f..96d990ab84 100644 --- a/docs/docs/self-hosting/deploy/.gitignore +++ b/docs/docs/self-hosting/deploy/.gitignore @@ -1 +1 @@ -*.pat \ No newline at end of file +*.pat diff --git a/docs/docs/self-hosting/manage/.gitignore b/docs/docs/self-hosting/manage/.gitignore new file mode 100644 index 0000000000..468fc82648 --- /dev/null +++ b/docs/docs/self-hosting/manage/.gitignore @@ -0,0 +1,3 @@ +**/*.pat +**/selfsigned.crt +**/selfsigned.key diff --git a/docs/docs/self-hosting/manage/reverseproxy/_caddy.mdx b/docs/docs/self-hosting/manage/reverseproxy/_caddy.mdx deleted file mode 100644 index 5b0b32b6ad..0000000000 --- a/docs/docs/self-hosting/manage/reverseproxy/_caddy.mdx +++ /dev/null @@ -1,25 +0,0 @@ -## TLS mode external - -``` -https://localhost { - reverse_proxy h2c://localhost:8080 - tls internal #only non production -} -``` - -## TLS mode enabled - -``` -https://localhost { - reverse_proxy https://localhost:8080 - tls internal #only non production -} -``` - -## TLS mode disabled - -``` -http://localhost { - reverse_proxy h2c://localhost:8080 -} -``` diff --git a/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_more.mdx b/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_more.mdx index e3e2a99400..9ab0d6c6f8 100644 --- a/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_more.mdx +++ b/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_more.mdx @@ -1,2 +1,2 @@ -- [Read more about ZITADELs TLS Modes](/self-hosting/manage/tls_modes) -- [Read more about how ZITADEL uses HTTP/2](/self-hosting/manage/http2) +- [Read more about Zitadel's TLS Modes](/self-hosting/manage/tls_modes) +- [Read more about how Zitadel uses HTTP/2](/self-hosting/manage/http2) diff --git a/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_overview.mdx b/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_overview.mdx index f72eb6eec5..edb77e1a05 100644 --- a/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_overview.mdx +++ b/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_overview.mdx @@ -1,8 +1,8 @@ import CodeBlock from '@theme/CodeBlock'; import ComposeYaml from "!!raw-loader!./docker-compose.yaml"; -<>With these examples, you create and run a minimal {props.link} configuration for ZITADEL with Docker Compose. -Whereas the guide focuses on the configuration for {props.name}, you can inspect the configurations for ZITADEL and the database in the base Docker Compose file. +<>With these examples, you create and run a minimal {props.link} configuration for Zitadel with Docker Compose. +Whereas the guide focuses on the configuration for {props.name}, you can inspect the configurations for the Zitadel API, the Zitadel login and the database in the base Docker Compose file.
base docker-compose.yaml {ComposeYaml} diff --git a/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_tls_mode.mdx b/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_tls_mode.mdx index 43663af486..491175a172 100644 --- a/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_tls_mode.mdx +++ b/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_tls_mode.mdx @@ -4,27 +4,27 @@ export const Description = ({mode, name}) => { let desc switch (mode) { case "disabled": - desc = <>Neither {name} nor ZITADEL terminates TLS. - Nevertheless, {name} forwards unencrypted HTTP/2 traffic, aka h2c, to ZITADEL.; + desc = <>Neither {name} nor Zitadel terminates TLS. + Nevertheless, {name} forwards unencrypted HTTP/2 traffic, aka h2c, to Zitadel.; break; case "external": - desc = <>{name} terminates TLS and forwards the requests to ZITADEL via unencrypted h2c. + desc = <>{name} terminates TLS and forwards the requests to Zitadel via unencrypted h2c. This example uses an unsafe self-signed certificate for {name}; break; case "enabled": - desc = <>{name} terminates TLS and forwards the requests to ZITADEL via encrypted HTTP/2. - This example uses an unsafe self-signed certificate for {name} and the same for ZITADEL.; + desc = <>{name} terminates TLS and forwards the requests to Zitadel via encrypted HTTP/2. + This example uses an unsafe self-signed certificate for {name} and the same for Zitadel.; break; } return ( <> {desc} - <>By executing the commands below, you will download the files necessary to run ZITADEL behind {name} with the following config: + <>By executing the commands below, you will download the files necessary to run Zitadel behind {name} with the following config: ) } export const Commands = ({mode, name, lower, configfilename}) => { - let genCert = '# Generate a self signed certificate and key.\nopenssl req -x509 -batch -subj "/CN=127.0.0.1.sslip.io/O=ZITADEL Demo" -nodes -newkey rsa:2048 -keyout ./selfsigned.key -out ./selfsigned.crt 2>/dev/null\n\n'; + let genCert = '# Generate a self signed certificate and key.\nopenssl req -x509 -batch -subj "/CN=127.0.0.1.sslip.io/O=Zitadel Demo" -nodes -newkey rsa:2048 -keyout ./selfsigned.key -out ./selfsigned.crt 2>/dev/null\n\n'; let connPort = "443" let connInsecureFlag = "--insecure " let connScheme = "https" @@ -47,8 +47,8 @@ export const Commands = ({mode, name, lower, configfilename}) => { {'wget $\{ZITADEL_CONFIG_FILES\}/'}{lower}{'/'}{configfilename}{' -O '}{configfilename}{' --quiet \n'} {'\n'} {genCert} - {'# Run the database, ZITADEL and '}{name}{'.'}{'\n'} - {'docker compose --file docker-compose-base.yaml --file docker-compose-'}{lower}{'.yaml up --detach --wait db zitadel-init zitadel-'}{mode}{'-tls proxy-'}{mode}{'-tls'}{'\n'} + {'# Run the database, and '}{name}{'.'}{'\n'} + {'docker compose --file docker-compose-base.yaml --file docker-compose-'}{lower}{'.yaml up --detach --wait db zitadel-init zitadel-'}{mode}{'-tls login-'}{mode}{'-tls proxy-'}{mode}{'-tls'}{'\n'} {'\n'} {'# Test that gRPC and HTTP APIs work. Empty brackets like {} means success.\n'} {'# Make sure you have the grpcurl cli installed on your machine https://github.com/fullstorydev/grpcurl?tab=readme-ov-file#installation\n'} @@ -85,6 +85,6 @@ export const LoginURL = ({mode}) => { If the console loads normally, you know that the HTTP and gRPC-Web and gRPC APIs are working correctly. - {'# You can now stop the database, ZITADEL and '}{props.providername}{'.'}{'\n'} + {'# You can now stop the database, the Zitadel API, the Zitadel login and '}{props.providername}{'.'}{'\n'} {'docker compose --file docker-compose-base.yaml --file docker-compose-'}{props.lower}{'.yaml down'}{'\n'} diff --git a/docs/docs/self-hosting/manage/reverseproxy/caddy/caddy.mdx b/docs/docs/self-hosting/manage/reverseproxy/caddy/caddy.mdx index 5fb9ea4014..ee3b2935ed 100644 --- a/docs/docs/self-hosting/manage/reverseproxy/caddy/caddy.mdx +++ b/docs/docs/self-hosting/manage/reverseproxy/caddy/caddy.mdx @@ -1,5 +1,5 @@ --- -title: Configure ZITADEL with Caddy +title: Configure Zitadel with Caddy sidebar_label: Caddy --- @@ -19,7 +19,7 @@ export const link = {providername} You can either setup your environment for TLS mode external or TLS mode enabled. - + --> ## TLS mode external - + + --> ## More Information diff --git a/docs/docs/self-hosting/manage/reverseproxy/nginx/docker-compose.yaml b/docs/docs/self-hosting/manage/reverseproxy/nginx/docker-compose.yaml index 524d50fc30..1ff9d9d39d 100644 --- a/docs/docs/self-hosting/manage/reverseproxy/nginx/docker-compose.yaml +++ b/docs/docs/self-hosting/manage/reverseproxy/nginx/docker-compose.yaml @@ -7,7 +7,7 @@ services: ports: - "80:80" networks: - - 'zitadel' + - app depends_on: zitadel-disabled-tls: condition: 'service_healthy' @@ -21,7 +21,7 @@ services: ports: - "443:443" networks: - - 'zitadel' + - app depends_on: zitadel-external-tls: condition: 'service_healthy' @@ -35,10 +35,7 @@ services: ports: - "443:443" networks: - - 'zitadel' + - app depends_on: zitadel-enabled-tls: condition: 'service_healthy' - -networks: - zitadel: \ No newline at end of file diff --git a/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx-disabled-tls.conf b/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx-disabled-tls.conf index 613d97ca64..5edeb75273 100644 --- a/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx-disabled-tls.conf +++ b/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx-disabled-tls.conf @@ -5,6 +5,10 @@ http { server { listen 80; http2 on; + location /ui/v2/login { + proxy_pass http://login-disabled-tls:3000; + proxy_set_header Host $host; + } location / { grpc_pass grpc://zitadel-disabled-tls:8080; grpc_set_header Host $host; diff --git a/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx-enabled-tls.conf b/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx-enabled-tls.conf index 397f1db728..26e5d7edf5 100644 --- a/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx-enabled-tls.conf +++ b/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx-enabled-tls.conf @@ -7,6 +7,11 @@ http { http2 on; ssl_certificate /etc/certs/selfsigned.crt; ssl_certificate_key /etc/certs/selfsigned.key; + location /ui/v2/login { + proxy_pass http://login-enabled-tls:3000; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-Proto https; + } location / { grpc_pass grpcs://zitadel-enabled-tls:8080; grpc_set_header Host $host; diff --git a/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx-external-tls.conf b/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx-external-tls.conf index 4c1eddb664..16bf993b77 100644 --- a/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx-external-tls.conf +++ b/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx-external-tls.conf @@ -7,9 +7,15 @@ http { http2 on; ssl_certificate /etc/certs/selfsigned.crt; ssl_certificate_key /etc/certs/selfsigned.key; + location /ui/v2/login { + proxy_pass http://login-external-tls:3000; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-Proto https; + } location / { grpc_pass grpc://zitadel-external-tls:8080; grpc_set_header Host $host; + grpc_set_header X-Forwarded-Proto https; } } } diff --git a/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx.mdx b/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx.mdx index fa3a9e75de..d6d6847ceb 100644 --- a/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx.mdx +++ b/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx.mdx @@ -1,5 +1,5 @@ --- -title: Configure ZITADEL with NGINX +title: Configure Zitadel with NGINX sidebar_label: NGINX --- @@ -19,9 +19,11 @@ export const link = {providername}; You can either setup your environment for TLS mode disabled, TLS mode external or TLS mode enabled. + ## TLS mode external diff --git a/docs/docs/self-hosting/manage/reverseproxy/reverse_proxy.mdx b/docs/docs/self-hosting/manage/reverseproxy/reverse_proxy.mdx index b37ef31231..85a724aae0 100644 --- a/docs/docs/self-hosting/manage/reverseproxy/reverse_proxy.mdx +++ b/docs/docs/self-hosting/manage/reverseproxy/reverse_proxy.mdx @@ -7,8 +7,9 @@ Check out one of the following guides to configure your favorite reverse proxy: - [Traefik](/self-hosting/manage/reverseproxy/traefik) - [NGINX](/self-hosting/manage/reverseproxy/nginx) - [Caddy](/self-hosting/manage/reverseproxy/caddy) - +- [Apache httpd](/self-hosting/manage/reverseproxy/httpd) - [Cloudflare](/self-hosting/manage/reverseproxy/cloudflare) - [Cloudflare Tunnel](/self-hosting/manage/reverseproxy/cloudflare_tunnel) -- [Fronting ZITADEL Cloud](/self-hosting/manage/reverseproxy/zitadel_cloud) +- [Fronting Zitadel Cloud](/self-hosting/manage/reverseproxy/zitadel_cloud) + \ No newline at end of file diff --git a/docs/docs/self-hosting/manage/reverseproxy/traefik/docker-compose.yaml b/docs/docs/self-hosting/manage/reverseproxy/traefik/docker-compose.yaml index a2dfab075b..f56512d58a 100644 --- a/docs/docs/self-hosting/manage/reverseproxy/traefik/docker-compose.yaml +++ b/docs/docs/self-hosting/manage/reverseproxy/traefik/docker-compose.yaml @@ -7,7 +7,7 @@ services: ports: - "80:80" networks: - - 'zitadel' + - app depends_on: zitadel-disabled-tls: condition: 'service_healthy' @@ -21,7 +21,7 @@ services: ports: - "443:443" networks: - - 'zitadel' + - app depends_on: zitadel-external-tls: condition: 'service_healthy' @@ -35,10 +35,7 @@ services: ports: - "443:443" networks: - - 'zitadel' + - app depends_on: zitadel-enabled-tls: condition: 'service_healthy' - -networks: - zitadel: \ No newline at end of file diff --git a/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik-disabled-tls.yaml b/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik-disabled-tls.yaml index 0dbf906fab..842b47738e 100644 --- a/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik-disabled-tls.yaml +++ b/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik-disabled-tls.yaml @@ -8,13 +8,24 @@ entrypoints: address: ":80" http: routers: - router: + zitadel: entryPoints: - "web" service: "zitadel" - rule: 'PathPrefix(`/`)' + rule: '!PathPrefix(`/ui/v2/login`)' + login: + entryPoints: + - "web" + service: "login" + rule: 'PathPrefix(`/ui/v2/login`)' services: zitadel: loadBalancer: + passHostHeader: true servers: - url: "h2c://zitadel-disabled-tls:8080" + login: + loadBalancer: + passHostHeader: true + servers: + - url: "http://login-disabled-tls:3000" \ No newline at end of file diff --git a/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik-enabled-tls.yaml b/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik-enabled-tls.yaml index b175d53a8e..1b70b4332c 100644 --- a/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik-enabled-tls.yaml +++ b/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik-enabled-tls.yaml @@ -8,21 +8,36 @@ entrypoints: address: ":443" http: routers: - router: + zitadel: entryPoints: - "web" service: "zitadel" - rule: 'PathPrefix(`/`)' + rule: '!PathPrefix(`/ui/v2/login`)' + tls: {} + login: + entryPoints: + - "web" + service: "login" + rule: 'PathPrefix(`/ui/v2/login`)' tls: {} services: zitadel: loadBalancer: serversTransport: "zitadel" + passHostHeader: true servers: - url: "https://zitadel-enabled-tls:8080" + login: + loadBalancer: + serversTransport: "login" + passHostHeader: true + servers: + - url: "http://login-enabled-tls:3000" serversTransports: zitadel: insecureSkipVerify: true + login: + insecureSkipVerify: true tls: stores: default: diff --git a/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik-external-tls.yaml b/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik-external-tls.yaml index e910590364..43f202e4fa 100644 --- a/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik-external-tls.yaml +++ b/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik-external-tls.yaml @@ -8,17 +8,29 @@ entrypoints: address: ":443" http: routers: - router: + zitadel: entryPoints: - "web" service: "zitadel" - rule: 'PathPrefix(`/`)' + rule: '!PathPrefix(`/ui/v2/login`)' + tls: {} + login: + entryPoints: + - "web" + service: "login" + rule: 'PathPrefix(`/ui/v2/login`)' tls: {} services: zitadel: loadBalancer: + passHostHeader: true servers: - url: "h2c://zitadel-external-tls:8080" + login: + loadBalancer: + passHostHeader: true + servers: + - url: "http://login-external-tls:3000" tls: stores: default: diff --git a/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik.mdx b/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik.mdx index 39769b229b..cf7ecacdc3 100644 --- a/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik.mdx +++ b/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik.mdx @@ -1,5 +1,5 @@ --- -title: Configure ZITADEL with Traefik +title: Configure Zitadel with Traefik sidebar_label: Traefik --- @@ -19,9 +19,11 @@ export const link = {providername} You can either setup your environment for TLS mode disabled, TLS mode external or TLS mode enabled. + ## TLS mode external diff --git a/docs/docs/self-hosting/manage/reverseproxy/zitadel_cloud/zitadel_cloud.mdx b/docs/docs/self-hosting/manage/reverseproxy/zitadel_cloud/zitadel_cloud.mdx index 1cbba5b3bd..ed074373b8 100644 --- a/docs/docs/self-hosting/manage/reverseproxy/zitadel_cloud/zitadel_cloud.mdx +++ b/docs/docs/self-hosting/manage/reverseproxy/zitadel_cloud/zitadel_cloud.mdx @@ -1,16 +1,16 @@ --- -title: Front ZITADEL Cloud with a CDN, WAF or Reverse Proxy -sidebar_label: Fronting ZITADEL Cloud +title: Front Zitadel Cloud with a CDN, WAF or Reverse Proxy +sidebar_label: Fronting Zitadel Cloud --- -## Fronting ZITADEL Cloud +## Fronting Zitadel Cloud -You can use your reverseproxy, content delivery network (CDN) or web application firewall (WAF) to front ZITADEL Cloud. +You can use your reverseproxy, content delivery network (CDN) or web application firewall (WAF) to front Zitadel Cloud. However we currently do not recommend this for production settings. -To configure your service that fronts ZITADEL please have a look at the vendors in this page. +To configure your service that fronts Zitadel please have a look at the vendors in this page. -## Things to look out for when fronting ZITADEL Cloud +## Things to look out for when fronting Zitadel Cloud -- Cache-control - ZITADEL Cloud uses a CDN to globally distribute data. Please try to avoid overriding this header as it may lead to sideeffects -- Rate Limits - ZITADEL Cloud uses a combination of static and dynamic rate limits. If you recieve occasional 429 headers you are rate limited. +- Cache-control - Zitadel Cloud uses a CDN to globally distribute data. Please try to avoid overriding this header as it may lead to sideeffects +- Rate Limits - Zitadel Cloud uses a combination of static and dynamic rate limits. If you recieve occasional 429 headers you are rate limited. diff --git a/docs/sidebars.js b/docs/sidebars.js index 11f905db8b..fc07e5be9f 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -1107,6 +1107,7 @@ module.exports = { "self-hosting/manage/reverseproxy/traefik/traefik", "self-hosting/manage/reverseproxy/nginx/nginx", "self-hosting/manage/reverseproxy/caddy/caddy", + "self-hosting/manage/reverseproxy/httpd/httpd", "self-hosting/manage/reverseproxy/cloudflare/cloudflare", "self-hosting/manage/reverseproxy/cloudflare_tunnel/cloudflare_tunnel", "self-hosting/manage/reverseproxy/zitadel_cloud/zitadel_cloud",