diff --git a/cmd/defaults.yaml b/cmd/defaults.yaml index cef9c0382..82fef4540 100644 --- a/cmd/defaults.yaml +++ b/cmd/defaults.yaml @@ -39,16 +39,15 @@ Telemetry: # Port ZITADEL will listen on Port: 8080 # ZITADEL_PORT -# Port ZITADEL is exposed on, it can differ from port e.g. if you proxy the traffic -# !!! Changing this after the initial setup breaks your system !!! +# ExternalPort is the port on which end users access ZITADEL. +# It can differ from Port e.g. if a reverse proxy forwards the traffic to ZITADEL +# Read more about external access: https://zitadel.com/docs/self-hosting/manage/custom-domain ExternalPort: 8080 # ZITADEL_EXTERNALPORT -# Domain/hostname ZITADEL is exposed externally -# !!! Changing this after the initial setup breaks your system !!! +# ExternalPort is the domain on which end users access ZITADEL. +# Read more about external access: https://zitadel.com/docs/self-hosting/manage/custom-domain ExternalDomain: localhost # ZITADEL_EXTERNALDOMAIN -# specifies if ZITADEL is exposed externally through TLS -# this must be set to true even if TLS is not enabled on ZITADEL itself -# but TLS traffic is terminated on a reverse proxy -# !!! Changing this after the initial setup breaks your system !!! +# ExternalSecure specifies if ZITADEL is exposed externally using HTTPS or HTTP. +# Read more about external access: https://zitadel.com/docs/self-hosting/manage/custom-domain ExternalSecure: true # ZITADEL_EXTERNALSECURE TLS: # If enabled, ZITADEL will serve all traffic over TLS (HTTPS and gRPC) diff --git a/cmd/ready/config.go b/cmd/ready/config.go index ea4c1290d..488dbe27d 100644 --- a/cmd/ready/config.go +++ b/cmd/ready/config.go @@ -9,12 +9,14 @@ import ( internal_authz "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/config/hook" + "github.com/zitadel/zitadel/internal/config/network" "github.com/zitadel/zitadel/internal/domain" ) type Config struct { Log *logging.Config Port uint16 + TLS network.TLS } func MustNewConfig(v *viper.Viper) *Config { diff --git a/cmd/ready/ready.go b/cmd/ready/ready.go index 679a1ac56..2b96db650 100644 --- a/cmd/ready/ready.go +++ b/cmd/ready/ready.go @@ -1,6 +1,7 @@ package ready import ( + "crypto/tls" "net" "net/http" "os" @@ -26,7 +27,13 @@ func New() *cobra.Command { } func ready(config *Config) bool { - res, err := http.Get("http://" + net.JoinHostPort("localhost", strconv.Itoa(int(config.Port))) + "/debug/ready") + scheme := "https" + if !config.TLS.Enabled { + scheme = "http" + } + // Checking the TLS cert is not in the scope of the readiness check + httpClient := http.Client{Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}} + res, err := httpClient.Get(scheme + "://" + net.JoinHostPort("localhost", strconv.Itoa(int(config.Port))) + "/debug/ready") if err != nil { logging.WithError(err).Warn("ready check failed") return false diff --git a/cmd/start/start.go b/cmd/start/start.go index 70f19b4e1..03651dc3e 100644 --- a/cmd/start/start.go +++ b/cmd/start/start.go @@ -367,16 +367,16 @@ func startAPIs( return fmt.Errorf("error starting admin repo: %w", err) } - if err := apis.RegisterServer(ctx, system.CreateServer(commands, queries, config.Database.DatabaseName(), config.DefaultInstance, config.ExternalDomain)); err != nil { + if err := apis.RegisterServer(ctx, system.CreateServer(commands, queries, config.Database.DatabaseName(), config.DefaultInstance, config.ExternalDomain), tlsConfig); err != nil { return err } - if err := apis.RegisterServer(ctx, admin.CreateServer(config.Database.DatabaseName(), commands, queries, config.SystemDefaults, config.ExternalSecure, keys.User, config.AuditLogRetention)); err != nil { + if err := apis.RegisterServer(ctx, admin.CreateServer(config.Database.DatabaseName(), commands, queries, config.SystemDefaults, config.ExternalSecure, keys.User, config.AuditLogRetention), tlsConfig); err != nil { return err } - if err := apis.RegisterServer(ctx, management.CreateServer(commands, queries, config.SystemDefaults, keys.User, config.ExternalSecure)); err != nil { + if err := apis.RegisterServer(ctx, management.CreateServer(commands, queries, config.SystemDefaults, keys.User, config.ExternalSecure), tlsConfig); err != nil { return err } - if err := apis.RegisterServer(ctx, auth.CreateServer(commands, queries, authRepo, config.SystemDefaults, keys.User, config.ExternalSecure)); err != nil { + if err := apis.RegisterServer(ctx, auth.CreateServer(commands, queries, authRepo, config.SystemDefaults, keys.User, config.ExternalSecure), tlsConfig); err != nil { return err } if err := apis.RegisterService(ctx, user_v2.CreateServer(commands, queries, keys.User, keys.IDPConfig, idp.CallbackURL(config.ExternalSecure), idp.SAMLRootURL(config.ExternalSecure))); err != nil { diff --git a/docs/docs/self-hosting/manage/custom-domain.md b/docs/docs/self-hosting/manage/custom-domain.md index ffff20772..57da59698 100644 --- a/docs/docs/self-hosting/manage/custom-domain.md +++ b/docs/docs/self-hosting/manage/custom-domain.md @@ -1,31 +1,65 @@ --- -title: Run ZITADEL on a Custom Domain -sidebar: Custom Domain +title: External ZITADEL Access +sidebar_label: Instance Not Found --- -# Run ZITADEL on a (Sub)domain of Your Choice +## Why do I get an "Instance not found" error? + +Also, ZITADEL has the [concept of virtual instances](/concepts/structure/instance#multiple-virtual-instances). +It uses a requests Host header to determine which virtual instance to use. +This is useful for multi-tenancy and resource sharing, for example in SaaS scenarios. +For most cases however, ZITADEL should run on exactly one domain. This guide assumes you are already familiar with [configuring ZITADEL](./configure). -You most probably need to configure these fields for making ZITADEL work on your custom domain. - ## Standard Config -For security reasons, ZITADEL only serves requests sent to the expected protocol, host and port. -If not using localhost as ExternalDomain, ExternalSecure must be true and you need to serve the ZITADEL console over HTTPS. +ZITADEL only serves requests sent to the expected protocol, host and port. +For local testing purposes, you can use following configuration: ```yaml -ExternalSecure: true -ExternalDomain: 'zitadel.my.domain' -ExternalPort: 443 +ExternalDomain: localhost +ExternalPort: 8080 +ExternalSecure: false ``` -## Database Initialization Steps Config +For productive setups however, we recommend using HTTPS and a custom domain: -ZITADEL creates random subdomains for each instance created. -However, for the first instance, this is most probably not the desired behavior. -In this case the `ExternalDomain`-field of the configuration is used. +```yaml +ExternalDomain: 'zitadel.my.domain' +ExternalPort: 443 +ExternalSecure: true +``` -## Example +## Changing ExternalDomain, ExternalPort or ExternalSecure + +You can change the ExternalDomain, ExternalPort and ExternalSecure configuration options at any time. +However, for ZITADEL to be able to pick up the changes, [you need to rerun ZITADELs setup phase](/self-hosting/manage/updating_scaling#the-setup-phase). + +## Running ZITADEL behind a Reverse Proxy + +If you run ZITADEL behind a reverse proxy, you need to ensure that it sends the correct request headers to ZITADEL. +The proxy must either ensure that +- the original *Host* header value is assigned to the *Forwarded* headers host directive. +- the original requests *Host* header value is unchanged by the proxy. + +Check out the [reverse proxy configuration examples](/self-hosting/manage/reverseproxy/reverse_proxy) for more information. + +## Organization Domains + +Note that by default, you cannot access ZITADEL at an organizations domain. +Organization level domains [are intended for routing users by their login methods to their correct organization](http://localhost:3000/docs/guides/solution-scenarios/domain-discovery). + +However, if you want to access ZITADEL at an organization domain, [you can add additional domains using the System API](/apis/resources/system/system-service-add-domain#adds-a-domain-to-an-instance). +Be aware that you won't automatically have the organizations context when you access ZITADEL like this. + +## Generated Subdomains + +ZITADEL creates random subdomains for [each new virtual instance](/concepts/structure/instance#multiple-virtual-instances). +You can immediately access the ZITADEL Console an APIs using these subdomains without further actions. + +## More Information + +- [Check out the production-near loadbalancing example with Traefik](/self-hosting/deploy/loadbalancing-example) +- [Explore some concrete proxy configuration examples for ZITADEL using the domain 127.0.0.1.sslip.io](/self-hosting/manage/reverseproxy/reverse_proxy) -Go to the [loadbalancing example with Traefik](/docs/self-hosting/deploy/loadbalancing-example) for seeing a working example configuration. diff --git a/docs/docs/self-hosting/manage/reverseproxy/_cloudflare_tunnel.mdx b/docs/docs/self-hosting/manage/reverseproxy/_cloudflare_tunnel.mdx deleted file mode 100644 index ea810b119..000000000 --- a/docs/docs/self-hosting/manage/reverseproxy/_cloudflare_tunnel.mdx +++ /dev/null @@ -1,3 +0,0 @@ -:::caution - -[The Cloudflare tunnel client currently has an issue which allows it not to force HTTP/2 usage towards the origin.](https://github.com/cloudflare/cloudflared/issues/682) \ No newline at end of file diff --git a/docs/docs/self-hosting/manage/reverseproxy/_httpd.mdx b/docs/docs/self-hosting/manage/reverseproxy/_httpd.mdx deleted file mode 100644 index b30d5494b..000000000 --- a/docs/docs/self-hosting/manage/reverseproxy/_httpd.mdx +++ /dev/null @@ -1,166 +0,0 @@ -## TLS mode external - -``` -LoadModule mpm_event_module modules/mod_mpm_event.so -LoadModule authn_file_module modules/mod_authn_file.so -LoadModule authn_core_module modules/mod_authn_core.so -LoadModule authz_host_module modules/mod_authz_host.so -LoadModule authz_groupfile_module modules/mod_authz_groupfile.so -LoadModule authz_user_module modules/mod_authz_user.so -LoadModule authz_core_module modules/mod_authz_core.so -LoadModule access_compat_module modules/mod_access_compat.so -LoadModule auth_basic_module modules/mod_auth_basic.so -LoadModule reqtimeout_module modules/mod_reqtimeout.so -LoadModule filter_module modules/mod_filter.so -LoadModule mime_module modules/mod_mime.so -LoadModule log_config_module modules/mod_log_config.so -LoadModule env_module modules/mod_env.so -LoadModule headers_module modules/mod_headers.so -LoadModule setenvif_module modules/mod_setenvif.so -LoadModule version_module modules/mod_version.so -LoadModule proxy_module modules/mod_proxy.so -LoadModule proxy_http_module modules/mod_proxy_http.so -LoadModule ssl_module modules/mod_ssl.so -LoadModule proxy_http2_module modules/mod_proxy_http2.so -LoadModule unixd_module modules/mod_unixd.so -LoadModule status_module modules/mod_status.so -LoadModule autoindex_module modules/mod_autoindex.so -LoadModule dir_module modules/mod_dir.so -LoadModule alias_module modules/mod_alias.so -LoadModule rewrite_module modules/mod_rewrite.so - -ServerRoot "/usr/local/apache2" -LogLevel warn -ErrorLog /proc/self/fd/2 -CustomLog /proc/self/fd/1 "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" - -ServerName my.domain -Listen 80 -Listen 443 - -SSLRandomSeed startup builtin -SSLRandomSeed connect builtin - - - ServerName my.domain - RewriteEngine On - RewriteCond %{HTTPS} off - RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} - - - - ServerName my.domain - ProxyPreserveHost On - SSLCertificateFile /certs/server.crt - SSLCertificateKeyFile /certs/server.key - ProxyPass / h2c://localhost:8080/ - ProxyPassReverse / h2c://localhost:8080/ - -``` - -## TLS mode enabled - -``` -LoadModule mpm_event_module modules/mod_mpm_event.so -LoadModule authn_file_module modules/mod_authn_file.so -LoadModule authn_core_module modules/mod_authn_core.so -LoadModule authz_host_module modules/mod_authz_host.so -LoadModule authz_groupfile_module modules/mod_authz_groupfile.so -LoadModule authz_user_module modules/mod_authz_user.so -LoadModule authz_core_module modules/mod_authz_core.so -LoadModule access_compat_module modules/mod_access_compat.so -LoadModule auth_basic_module modules/mod_auth_basic.so -LoadModule reqtimeout_module modules/mod_reqtimeout.so -LoadModule filter_module modules/mod_filter.so -LoadModule mime_module modules/mod_mime.so -LoadModule log_config_module modules/mod_log_config.so -LoadModule env_module modules/mod_env.so -LoadModule headers_module modules/mod_headers.so -LoadModule setenvif_module modules/mod_setenvif.so -LoadModule version_module modules/mod_version.so -LoadModule proxy_module modules/mod_proxy.so -LoadModule proxy_http_module modules/mod_proxy_http.so -LoadModule ssl_module modules/mod_ssl.so -LoadModule proxy_http2_module modules/mod_proxy_http2.so -LoadModule unixd_module modules/mod_unixd.so -LoadModule status_module modules/mod_status.so -LoadModule autoindex_module modules/mod_autoindex.so -LoadModule dir_module modules/mod_dir.so -LoadModule alias_module modules/mod_alias.so -LoadModule rewrite_module modules/mod_rewrite.so -LoadModule http2_module modules/mod_http2.so - -ServerRoot "/usr/local/apache2" -LogLevel debug -ErrorLog /proc/self/fd/2 -CustomLog /proc/self/fd/1 "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" - -ServerName my.domain -Listen 80 -Listen 443 - -SSLRandomSeed startup builtin -SSLRandomSeed connect builtin - - - RewriteEngine On - RewriteCond %{HTTPS} off - RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} - - - - ProxyPreserveHost On - SSLEngine on - SSLProxyEngine on - SSLCertificateFile /certs/server.crt - SSLCertificateKeyFile /certs/server.key - ProxyPass / h2://localhost:8080/ - -``` - -## TLS mode disabled - -``` -LoadModule mpm_event_module modules/mod_mpm_event.so -LoadModule authn_file_module modules/mod_authn_file.so -LoadModule authn_core_module modules/mod_authn_core.so -LoadModule authz_host_module modules/mod_authz_host.so -LoadModule authz_groupfile_module modules/mod_authz_groupfile.so -LoadModule authz_user_module modules/mod_authz_user.so -LoadModule authz_core_module modules/mod_authz_core.so -LoadModule access_compat_module modules/mod_access_compat.so -LoadModule auth_basic_module modules/mod_auth_basic.so -LoadModule reqtimeout_module modules/mod_reqtimeout.so -LoadModule filter_module modules/mod_filter.so -LoadModule mime_module modules/mod_mime.so -LoadModule log_config_module modules/mod_log_config.so -LoadModule env_module modules/mod_env.so -LoadModule headers_module modules/mod_headers.so -LoadModule setenvif_module modules/mod_setenvif.so -LoadModule version_module modules/mod_version.so -LoadModule proxy_module modules/mod_proxy.so -LoadModule proxy_http_module modules/mod_proxy_http.so -LoadModule ssl_module modules/mod_ssl.so -LoadModule proxy_http2_module modules/mod_proxy_http2.so -LoadModule unixd_module modules/mod_unixd.so -LoadModule status_module modules/mod_status.so -LoadModule autoindex_module modules/mod_autoindex.so -LoadModule dir_module modules/mod_dir.so -LoadModule alias_module modules/mod_alias.so -LoadModule rewrite_module modules/mod_rewrite.so - -ServerRoot "/usr/local/apache2" -LogLevel warn -ErrorLog /proc/self/fd/2 -CustomLog /proc/self/fd/1 "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" - -ServerName my.domain -Listen 80 - - - ServerName my.domain - ProxyPreserveHost On - ProxyPass / h2c://localhost:8080/ - ProxyPassReverse / h2c://localhost:8080/ - -``` diff --git a/docs/docs/self-hosting/manage/reverseproxy/_more.mdx b/docs/docs/self-hosting/manage/reverseproxy/_more.mdx deleted file mode 100644 index d88d76c23..000000000 --- a/docs/docs/self-hosting/manage/reverseproxy/_more.mdx +++ /dev/null @@ -1,4 +0,0 @@ -## More information - -- [You can read here about the TLS Modes](/self-hosting/manage/tls_modes) -- [And here about how ZITADEL makes use of HTTP/2](/self-hosting/manage/http2) diff --git a/docs/docs/self-hosting/manage/reverseproxy/_nginx.mdx b/docs/docs/self-hosting/manage/reverseproxy/_nginx.mdx deleted file mode 100644 index aa738ffc6..000000000 --- a/docs/docs/self-hosting/manage/reverseproxy/_nginx.mdx +++ /dev/null @@ -1,95 +0,0 @@ -## TLS mode external - -``` -worker_processes 1; -events { - worker_connections 1024; -} - -http { - server { - listen 443; - - ssl_certificate ssl/certificate.pem; - ssl_certificate_key ssl/key.pem; - - location / { - grpc_pass grpc://localhost:8080; - grpc_set_header Host $host; - } - } -} -``` - -:::info -If another port than the default HTTPS port 443 is used replace - -` grpc_set_header Host $host;` - -with - -` grpc_set_header Host $host:$server_port;` -::: - -## TLS mode enabled - -``` -worker_processes 1; -events { - worker_connections 1024; -} - -http { - server { - listen 443; - - ssl_certificate ssl/certificate.pem; - ssl_certificate_key ssl/key.pem; - - location / { - grpc_pass grpcs://localhost:8080; - grpc_set_header Host $host; - } - } -} -``` - -:::info -If another port than the default HTTPS port 443 is used replace - -` grpc_set_header Host $host;` - -with - -` grpc_set_header Host $host:$server_port;` -::: - -## TLS mode disabled - -``` -worker_processes 1; -events { - worker_connections 1024; -} - -http { - server { - listen 80; - - location / { - grpc_pass grpc://localhost:8080; - grpc_set_header Host $host; - } - } -} -``` - -:::info -If another port than the default HTTP port 80 is used replace - -` grpc_set_header Host $host;` - -with - -` grpc_set_header Host $host:$server_port;` -::: diff --git a/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_more.mdx b/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_more.mdx new file mode 100644 index 000000000..e3e2a9940 --- /dev/null +++ b/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_more.mdx @@ -0,0 +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) diff --git a/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_overview.mdx b/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_overview.mdx new file mode 100644 index 000000000..3200ddf37 --- /dev/null +++ b/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_overview.mdx @@ -0,0 +1,16 @@ +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.link}, you can inspect the configurations for ZITADEL and the database in the base Docker Compose file. +
+ base docker-compose.yaml + {ComposeYaml} +
+ +<>For running {props.link}, you will extend the base Docker Compose file with the {props.link} specific Docker Compose file. + +
+ specific docker-compose.yaml + {props.compose} +
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 new file mode 100644 index 000000000..f4a780473 --- /dev/null +++ b/docs/docs/self-hosting/manage/reverseproxy/_proxy_guide_tls_mode.mdx @@ -0,0 +1,90 @@ +import CodeBlock from '@theme/CodeBlock'; + +export const Description = ({mode, link}) => { + let desc + switch (mode) { + case "disabled": + desc = <>Neither {link} nor ZITADEL terminates TLS. + Nevertheless, {link} forwards unencrypted HTTP/2 traffic, aka h2c, to ZITADEL.; + break; + case "external": + desc = <>{link} terminates TLS and forwards the requests to ZITADEL via unencrypted h2c. + This example uses an unsafe self-signed certificate for {link}; + break; + case "enabled": + desc = <>{link} terminates TLS and forwards the requests to ZITADEL via encrypted HTTP/2. + This example uses an unsafe self-signed certificate for {link} and the same for ZITADEL.; + break; + } + return ( + <> + {desc} + <>By executing the commands below, you will download the files necessary to run ZITADEL behind {link} 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\n\n'; + let connPort = "443" + let connInsecureFlag = "--insecure " + let connScheme = "https" + let grpcPlainTextFlag = "" + if (mode === "disabled") { + genCert = '' + connPort = "80" + grpcPlainTextFlag = "--plaintext " + connScheme = "http" + // We only need that flag for TLS connections with the self-signed cert + connInsecureFlag = "" + } + return ( +
+ + {'# Download the configuration files.'}{'\n'} + {'export ZITADEL_CONFIG_FILES=https://raw.githubusercontent.com/zitadel/zitadel/main/docs/docs/self-hosting/manage/reverseproxy\n'} + {`wget $\{ZITADEL_CONFIG_FILES\}/docker-compose.yaml -O docker-compose-base.yaml`}{'\n'} + {'wget $\{ZITADEL_CONFIG_FILES\}/'}{lower}{'/docker-compose.yaml -O docker-compose-'}{lower}{'.yaml'}{'\n'} + {'wget $\{ZITADEL_CONFIG_FILES\}/'}{lower}{'/'}{configfilename}{' -O '}{configfilename}{'\n'} + {'\n'} + {genCert} + {'# Run the database, ZITADEL and '}{name}{'.'}{'\n'} + {'docker compose --file docker-compose-base.yaml --file docker-compose-'}{lower}{'.yaml up --detach proxy-'}{mode}{'-tls'}{'\n'} + {'\n'} + {'# Test that gRPC and HTTP APIs work. Empty brackets like {} means success.\n'} + {'sleep 3\n'} + {'grpcurl '}{connInsecureFlag}{grpcPlainTextFlag}{'127.0.0.1.sslip.io:'}{connPort}{' zitadel.admin.v1.AdminService/Healthz\n'} + {'curl '}{connInsecureFlag}{connScheme}{'://127.0.0.1.sslip.io:'}{connPort}{'/admin/v1/healthz\n'} + +
+ ) +} + +export const LoginURL = ({mode}) => { + let scheme = "https"; + if (mode === "disabled") { + scheme = "http" + } + const url = scheme + "://127.0.0.1.sslip.io/ui/console"; + return {url} +} + + + +
+ {props.configfilename} + {props.configfilecontent} +
+ + + +<>When the docker compose command exits successfully, go to and log in: + +- **username**: *zitadel-admin@zitadel.127.0.0.1.sslip.io* +- **password**: *Password1!* + +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'} + {'docker compose --file docker-compose-base.yaml --file docker-compose-'}{props.lower}{'.yaml down'}{'\n'} + diff --git a/docs/docs/self-hosting/manage/reverseproxy/_traefik.mdx b/docs/docs/self-hosting/manage/reverseproxy/_traefik.mdx deleted file mode 100644 index f519e4523..000000000 --- a/docs/docs/self-hosting/manage/reverseproxy/_traefik.mdx +++ /dev/null @@ -1,150 +0,0 @@ -## TLS mode external - -```yaml -entrypoints: - web: - address: ":80" - websecure: - address: ":443" -tls: - stores: - default: - defaultCertificate: -providers: - file: - filename: /etc/traefik/traefik.yaml -http: - middlewares: - zitadel: - headers: - isDevelopment: false - allowedHosts: - - 'localhost' - customRequestHeaders: - :authority: 'localhost' - redirect-to-https: - redirectScheme: - scheme: https - port: 443 - permanent: true - routers: - router0: - entryPoints: - - web - middlewares: - - redirect-to-https - rule: 'HostRegexp(`localhost`, `{subdomain:[a-z]+}.localhost`)' - service: zitadel - router1: - entryPoints: - - websecure - service: zitadel - middlewares: - - zitadel - rule: 'HostRegexp(`localhost`, `{subdomain:[a-z]+}.localhost`)' - tls: - domains: - - main: "localhost" - sans: - - "*.localhost" - - "localhost" - services: - zitadel: - loadBalancer: - servers: - - url: h2c://localhost:8080 - passHostHeader: true -``` - -## TLS mode enabled - -```yaml -entrypoints: - web: - address: ":80" - websecure: - address: ":443" -tls: - stores: - default: - defaultCertificate: -providers: - file: - filename: /etc/traefik/traefik.yaml -http: - middlewares: - zitadel: - headers: - isDevelopment: false - allowedHosts: - - 'localhost' - customRequestHeaders: - :authority: 'localhost' - redirect-to-https: - redirectScheme: - scheme: https - port: 443 - permanent: true - routers: - router0: - entryPoints: - - web - middlewares: - - redirect-to-https - rule: 'HostRegexp(`localhost`, `{subdomain:[a-z]+}.localhost`)' - service: zitadel - # The actual ZITADEL router - router1: - entryPoints: - - websecure - service: zitadel - middlewares: - - zitadel - rule: 'HostRegexp(`localhost`, `{subdomain:[a-z]+}.localhost`)' - tls: - domains: - - main: "localhost" - sans: - - "*.localhost" - - "localhost" - services: - zitadel: - loadBalancer: - servers: - - url: https://localhost:8080 - passHostHeader: true -``` - -## TLS mode disabled - -```yaml -entrypoints: - web: - address: ":80" -providers: - file: - filename: /etc/traefik/traefik.yaml -http: - middlewares: - zitadel: - headers: - isDevelopment: false - allowedHosts: - - 'localhost' - customRequestHeaders: - :authority: 'localhost' - routers: - router0: - entryPoints: - - web - middlewares: - - redirect-to-https - rule: 'HostRegexp(`localhost`, `{subdomain:[a-z]+}.localhost`)' - service: zitadel - services: - zitadel: - loadBalancer: - servers: - - url: h2c://localhost:8080 - passHostHeader: true -``` diff --git a/docs/docs/self-hosting/manage/reverseproxy/caddy/caddy.mdx b/docs/docs/self-hosting/manage/reverseproxy/caddy/caddy.mdx new file mode 100644 index 000000000..20a00dae9 --- /dev/null +++ b/docs/docs/self-hosting/manage/reverseproxy/caddy/caddy.mdx @@ -0,0 +1,38 @@ +--- +title: Configure ZITADEL with Caddy +sidebar_label: Caddy +--- + +import ProxyGuideOverview from '../_proxy_guide_overview.mdx'; +import ProxyGuideTLSMode from '../_proxy_guide_tls_mode.mdx'; +import ProxyGuideMore from '../_proxy_guide_more.mdx'; +import Compose from "!!raw-loader!./docker-compose.yaml"; +import ConfigDisabled from "!!raw-loader!./disabled-tls.Caddyfile"; +import ConfigExternal from "!!raw-loader!./external-tls.Caddyfile"; +import ConfigEnabled from "!!raw-loader!./enabled-tls.Caddyfile"; + +export const providername = 'Caddy'; +export const lower = "caddy"; +export const link = {providername} + + + +You can either setup your environment for TLS mode external or TLS mode enabled. + + + +## TLS mode external + + + +## TLS mode enabled + + + +## More Information + + diff --git a/docs/docs/self-hosting/manage/reverseproxy/caddy/disabled-tls.Caddyfile b/docs/docs/self-hosting/manage/reverseproxy/caddy/disabled-tls.Caddyfile new file mode 100644 index 000000000..db5b3eb94 --- /dev/null +++ b/docs/docs/self-hosting/manage/reverseproxy/caddy/disabled-tls.Caddyfile @@ -0,0 +1,3 @@ +http://127.0.0.1.sslip.io { + reverse_proxy h2c://zitadel-disabled-tls:8080 +} diff --git a/docs/docs/self-hosting/manage/reverseproxy/caddy/docker-compose.yaml b/docs/docs/self-hosting/manage/reverseproxy/caddy/docker-compose.yaml new file mode 100644 index 000000000..f3a724053 --- /dev/null +++ b/docs/docs/self-hosting/manage/reverseproxy/caddy/docker-compose.yaml @@ -0,0 +1,37 @@ +version: '3.8' + +services: + + proxy-disabled-tls: + image: "caddy:2.7.5-alpine" + volumes: + - "./disabled-tls.Caddyfile:/etc/caddy/Caddyfile:ro" + ports: + - "80:80" + depends_on: + zitadel-disabled-tls: + condition: 'service_healthy' + + proxy-external-tls: + image: "caddy:2.7.5-alpine" + volumes: + - "./external-tls.Caddyfile:/etc/caddy/Caddyfile:ro" + - "./selfsigned.crt:/etc/certs/selfsigned.crt:ro" + - "./selfsigned.key:/etc/certs/selfsigned.key:ro" + ports: + - "443:443" + depends_on: + zitadel-external-tls: + condition: 'service_healthy' + + proxy-enabled-tls: + image: "caddy:2.7.5-alpine" + volumes: + - "./enabled-tls.Caddyfile:/etc/caddy/Caddyfile:ro" + - "./selfsigned.crt:/etc/certs/selfsigned.crt:ro" + - "./selfsigned.key:/etc/certs/selfsigned.key:ro" + ports: + - "443:443" + depends_on: + zitadel-enabled-tls: + condition: 'service_healthy' diff --git a/docs/docs/self-hosting/manage/reverseproxy/caddy/enabled-tls.Caddyfile b/docs/docs/self-hosting/manage/reverseproxy/caddy/enabled-tls.Caddyfile new file mode 100644 index 000000000..5040b1daa --- /dev/null +++ b/docs/docs/self-hosting/manage/reverseproxy/caddy/enabled-tls.Caddyfile @@ -0,0 +1,8 @@ +https://127.0.0.1.sslip.io { + tls /etc/certs/selfsigned.crt /etc/certs/selfsigned.key + reverse_proxy https://zitadel-enabled-tls:8080 { + transport http { + tls_insecure_skip_verify + } + } +} diff --git a/docs/docs/self-hosting/manage/reverseproxy/caddy/external-tls.Caddyfile b/docs/docs/self-hosting/manage/reverseproxy/caddy/external-tls.Caddyfile new file mode 100644 index 000000000..867b9f95b --- /dev/null +++ b/docs/docs/self-hosting/manage/reverseproxy/caddy/external-tls.Caddyfile @@ -0,0 +1,4 @@ +https://127.0.0.1.sslip.io { + tls /etc/certs/selfsigned.crt /etc/certs/selfsigned.key + reverse_proxy h2c://zitadel-external-tls:8080 +} diff --git a/docs/docs/self-hosting/manage/reverseproxy/_cloudflare.mdx b/docs/docs/self-hosting/manage/reverseproxy/cloudflare/cloudflare.mdx similarity index 92% rename from docs/docs/self-hosting/manage/reverseproxy/_cloudflare.mdx rename to docs/docs/self-hosting/manage/reverseproxy/cloudflare/cloudflare.mdx index d18431107..7810b909c 100644 --- a/docs/docs/self-hosting/manage/reverseproxy/_cloudflare.mdx +++ b/docs/docs/self-hosting/manage/reverseproxy/cloudflare/cloudflare.mdx @@ -1,3 +1,8 @@ +--- +title: Configure ZITADEL with Cloudflare +sidebar_label: Cloudflare +--- + ## Settings - [Make sure HTTP/2 is enabled](https://support.cloudflare.com/hc/en-us/articles/200168076-Understanding-Cloudflare-HTTP-2-and-HTTP-3-Support) diff --git a/docs/docs/self-hosting/manage/reverseproxy/cloudflare_tunnel/cloudflare_tunnel.mdx b/docs/docs/self-hosting/manage/reverseproxy/cloudflare_tunnel/cloudflare_tunnel.mdx new file mode 100644 index 000000000..829123637 --- /dev/null +++ b/docs/docs/self-hosting/manage/reverseproxy/cloudflare_tunnel/cloudflare_tunnel.mdx @@ -0,0 +1,8 @@ +--- +title: Configure ZITADEL with Cloudflare Tunnel +sidebar_label: Cloudflare Tunnel +--- + +:::caution + +[The Cloudflare tunnel client currently has an issue which disallows it to force HTTP/2 usage towards the origin.](https://github.com/cloudflare/cloudflared/issues/682) diff --git a/docs/docs/self-hosting/manage/reverseproxy/docker-compose.yaml b/docs/docs/self-hosting/manage/reverseproxy/docker-compose.yaml new file mode 100644 index 000000000..885713731 --- /dev/null +++ b/docs/docs/self-hosting/manage/reverseproxy/docker-compose.yaml @@ -0,0 +1,90 @@ +version: '3.8' + +services: + + zitadel-disabled-tls: + extends: + service: zitadel-init + command: 'start-from-setup --masterkey "MasterkeyNeedsToHave32Characters" --config /zitadel.yaml --steps /zitadel.yaml' + environment: + - ZITADEL_EXTERNALPORT=80 + - ZITADEL_EXTERNALSECURE=false + - ZITADEL_TLS_ENABLED=false + depends_on: + zitadel-init: + condition: 'service_completed_successfully' + db: + condition: 'service_healthy' + + zitadel-external-tls: + extends: + service: zitadel-init + command: 'start-from-setup --masterkey "MasterkeyNeedsToHave32Characters" --config /zitadel.yaml --steps /zitadel.yaml' + environment: + - ZITADEL_EXTERNALPORT=443 + - ZITADEL_EXTERNALSECURE=true + - ZITADEL_TLS_ENABLED=false + depends_on: + zitadel-init: + condition: 'service_completed_successfully' + db: + condition: 'service_healthy' + + zitadel-enabled-tls: + extends: + service: zitadel-init + command: 'start-from-setup --masterkey "MasterkeyNeedsToHave32Characters" --config /zitadel.yaml --steps /zitadel.yaml' + environment: + - ZITADEL_EXTERNALPORT=443 + - ZITADEL_EXTERNALSECURE=true + - ZITADEL_TLS_ENABLED=true + - ZITADEL_TLS_CERTPATH=/etc/certs/selfsigned.crt + - ZITADEL_TLS_KEYPATH=/etc/certs/selfsigned.key + volumes: + - ./selfsigned.crt:/etc/certs/selfsigned.crt + - ./selfsigned.key:/etc/certs/selfsigned.key + depends_on: + zitadel-init: + condition: 'service_completed_successfully' + db: + condition: 'service_healthy' + + zitadel-init: + user: '$UID' + image: '${ZITADEL_IMAGE:-ghcr.io/zitadel/zitadel:latest}' + command: 'init --config /zitadel.yaml' + depends_on: + db: + condition: 'service_healthy' + environment: + # Using an external domain other than localhost proofs, that the proxy configuration works. + # If ZITADEL can't resolve a requests original host to this domain, + # it will return a 404 Instance not found error. + - ZITADEL_EXTERNALDOMAIN=127.0.0.1.sslip.io + # ZITADEL accesses the database via the docker network. + - ZITADEL_DATABASE_COCKROACH_HOST=db + # In case something doesn't work as expected, + # it can be handy to be able to read the access logs. + - ZITADEL_LOGSTORE_ACCESS_STDOUT_ENABLED=true + # For convenience, ZITADEL should not ask to change the initial admin users password. + - ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORDCHANGEREQUIRED=false + healthcheck: + test: ["CMD", "/app/zitadel", "ready"] + interval: '10s' + timeout: '5s' + retries: 5 + start_period: '10s' + + db: + restart: 'always' + image: 'cockroachdb/cockroach:latest' + command: 'start-single-node --insecure --http-addr :9090' + healthcheck: + test: ['CMD', 'curl', '-f', 'http://localhost:9090/health?ready=1'] + interval: '10s' + timeout: '30s' + retries: 5 + start_period: '20s' + ports: + - "26257:26257" + - "9090:9090" diff --git a/docs/docs/self-hosting/manage/reverseproxy/httpd/docker-compose.yaml b/docs/docs/self-hosting/manage/reverseproxy/httpd/docker-compose.yaml new file mode 100644 index 000000000..72e06b976 --- /dev/null +++ b/docs/docs/self-hosting/manage/reverseproxy/httpd/docker-compose.yaml @@ -0,0 +1,37 @@ +version: '3.8' + +services: + + proxy-disabled-tls: + image: "httpd:2.4.58-alpine" + volumes: + - "./httpd-disabled-tls.conf:/usr/local/apache2/conf/httpd.conf" + ports: + - "80:80" + depends_on: + zitadel-disabled-tls: + condition: 'service_healthy' + + proxy-external-tls: + image: "httpd:2.4.58-alpine" + volumes: + - "./httpd-external-tls.conf:/usr/local/apache2/conf/httpd.conf" + - "./selfsigned.crt:/etc/certs/selfsigned.crt:ro" + - "./selfsigned.key:/etc/certs/selfsigned.key:ro" + ports: + - "443:443" + depends_on: + zitadel-external-tls: + condition: 'service_healthy' + + proxy-enabled-tls: + image: "httpd:2.4.58-alpine" + volumes: + - "./httpd-enabled-tls.conf:/usr/local/apache2/conf/httpd.conf" + - "./selfsigned.crt:/etc/certs/selfsigned.crt:ro" + - "./selfsigned.key:/etc/certs/selfsigned.key:ro" + ports: + - "443:443" + depends_on: + zitadel-enabled-tls: + condition: 'service_healthy' diff --git a/docs/docs/self-hosting/manage/reverseproxy/httpd/httpd-disabled-tls.conf b/docs/docs/self-hosting/manage/reverseproxy/httpd/httpd-disabled-tls.conf new file mode 100644 index 000000000..6d745f34e --- /dev/null +++ b/docs/docs/self-hosting/manage/reverseproxy/httpd/httpd-disabled-tls.conf @@ -0,0 +1,39 @@ +LoadModule mpm_event_module modules/mod_mpm_event.so +LoadModule authn_file_module modules/mod_authn_file.so +LoadModule authn_core_module modules/mod_authn_core.so +LoadModule authz_host_module modules/mod_authz_host.so +LoadModule authz_groupfile_module modules/mod_authz_groupfile.so +LoadModule authz_user_module modules/mod_authz_user.so +LoadModule authz_core_module modules/mod_authz_core.so +LoadModule access_compat_module modules/mod_access_compat.so +LoadModule auth_basic_module modules/mod_auth_basic.so +LoadModule reqtimeout_module modules/mod_reqtimeout.so +LoadModule filter_module modules/mod_filter.so +LoadModule mime_module modules/mod_mime.so +LoadModule log_config_module modules/mod_log_config.so +LoadModule env_module modules/mod_env.so +LoadModule headers_module modules/mod_headers.so +LoadModule setenvif_module modules/mod_setenvif.so +LoadModule version_module modules/mod_version.so +LoadModule proxy_module modules/mod_proxy.so +LoadModule proxy_http_module modules/mod_proxy_http.so +LoadModule ssl_module modules/mod_ssl.so +LoadModule proxy_http2_module modules/mod_proxy_http2.so +LoadModule unixd_module modules/mod_unixd.so +LoadModule status_module modules/mod_status.so +LoadModule autoindex_module modules/mod_autoindex.so +LoadModule dir_module modules/mod_dir.so +LoadModule alias_module modules/mod_alias.so +LoadModule rewrite_module modules/mod_rewrite.so + +ServerRoot "/usr/local/apache2" +LogLevel debug +ErrorLog /proc/self/fd/2 +CustomLog /proc/self/fd/1 "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" + +Listen 80 + + + ProxyPass / h2c://zitadel-disabled-tls:8080/ + ProxyPreserveHost on + diff --git a/docs/docs/self-hosting/manage/reverseproxy/httpd/httpd-enabled-tls.conf b/docs/docs/self-hosting/manage/reverseproxy/httpd/httpd-enabled-tls.conf new file mode 100644 index 000000000..c398d52f4 --- /dev/null +++ b/docs/docs/self-hosting/manage/reverseproxy/httpd/httpd-enabled-tls.conf @@ -0,0 +1,47 @@ +LoadModule mpm_event_module modules/mod_mpm_event.so +LoadModule authn_file_module modules/mod_authn_file.so +LoadModule authn_core_module modules/mod_authn_core.so +LoadModule authz_host_module modules/mod_authz_host.so +LoadModule authz_groupfile_module modules/mod_authz_groupfile.so +LoadModule authz_user_module modules/mod_authz_user.so +LoadModule authz_core_module modules/mod_authz_core.so +LoadModule access_compat_module modules/mod_access_compat.so +LoadModule auth_basic_module modules/mod_auth_basic.so +LoadModule reqtimeout_module modules/mod_reqtimeout.so +LoadModule filter_module modules/mod_filter.so +LoadModule mime_module modules/mod_mime.so +LoadModule log_config_module modules/mod_log_config.so +LoadModule env_module modules/mod_env.so +LoadModule headers_module modules/mod_headers.so +LoadModule setenvif_module modules/mod_setenvif.so +LoadModule version_module modules/mod_version.so +LoadModule proxy_module modules/mod_proxy.so +LoadModule proxy_http_module modules/mod_proxy_http.so +LoadModule ssl_module modules/mod_ssl.so +LoadModule proxy_http2_module modules/mod_proxy_http2.so +LoadModule unixd_module modules/mod_unixd.so +LoadModule status_module modules/mod_status.so +LoadModule autoindex_module modules/mod_autoindex.so +LoadModule dir_module modules/mod_dir.so +LoadModule alias_module modules/mod_alias.so +LoadModule rewrite_module modules/mod_rewrite.so +LoadModule http2_module modules/mod_http2.so + +ServerRoot "/usr/local/apache2" +LogLevel debug +ErrorLog /proc/self/fd/2 +CustomLog /proc/self/fd/1 "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" + +Listen 443 + +SSLRandomSeed startup builtin +SSLRandomSeed connect builtin + + + ProxyPass / h2://zitadel-enabled-tls:8080/ + ProxyPreserveHost on + SSLEngine on + SSLProxyEngine on + SSLCertificateFile /etc/certs/selfsigned.crt + SSLCertificateKeyFile /etc/certs/selfsigned.key + diff --git a/docs/docs/self-hosting/manage/reverseproxy/httpd/httpd-external-tls.conf b/docs/docs/self-hosting/manage/reverseproxy/httpd/httpd-external-tls.conf new file mode 100644 index 000000000..7bcd6c3d9 --- /dev/null +++ b/docs/docs/self-hosting/manage/reverseproxy/httpd/httpd-external-tls.conf @@ -0,0 +1,43 @@ +LoadModule mpm_event_module modules/mod_mpm_event.so +LoadModule authn_file_module modules/mod_authn_file.so +LoadModule authn_core_module modules/mod_authn_core.so +LoadModule authz_host_module modules/mod_authz_host.so +LoadModule authz_groupfile_module modules/mod_authz_groupfile.so +LoadModule authz_user_module modules/mod_authz_user.so +LoadModule authz_core_module modules/mod_authz_core.so +LoadModule access_compat_module modules/mod_access_compat.so +LoadModule auth_basic_module modules/mod_auth_basic.so +LoadModule reqtimeout_module modules/mod_reqtimeout.so +LoadModule filter_module modules/mod_filter.so +LoadModule mime_module modules/mod_mime.so +LoadModule log_config_module modules/mod_log_config.so +LoadModule env_module modules/mod_env.so +LoadModule headers_module modules/mod_headers.so +LoadModule setenvif_module modules/mod_setenvif.so +LoadModule version_module modules/mod_version.so +LoadModule proxy_module modules/mod_proxy.so +LoadModule proxy_http_module modules/mod_proxy_http.so +LoadModule ssl_module modules/mod_ssl.so +LoadModule proxy_http2_module modules/mod_proxy_http2.so +LoadModule unixd_module modules/mod_unixd.so +LoadModule status_module modules/mod_status.so +LoadModule autoindex_module modules/mod_autoindex.so +LoadModule dir_module modules/mod_dir.so +LoadModule alias_module modules/mod_alias.so +LoadModule rewrite_module modules/mod_rewrite.so +LoadModule http2_module modules/mod_http2.so + +LogLevel debug +ErrorLog /proc/self/fd/2 +CustomLog /proc/self/fd/1 "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" + +Listen 443 + + + ProxyPass / h2c://zitadel-external-tls:8080/ + ProxyPassReverse / h2c://zitadel-external-tls:8080/ + ProxyPreserveHost on + SSLEngine on + SSLCertificateFile /etc/certs/selfsigned.crt + SSLCertificateKeyFile /etc/certs/selfsigned.key + diff --git a/docs/docs/self-hosting/manage/reverseproxy/httpd/httpd.mdx b/docs/docs/self-hosting/manage/reverseproxy/httpd/httpd.mdx new file mode 100644 index 000000000..dc17e9387 --- /dev/null +++ b/docs/docs/self-hosting/manage/reverseproxy/httpd/httpd.mdx @@ -0,0 +1,38 @@ +--- +title: Configure ZITADEL with Apache httpd +sidebar_label: Apache httpd +--- + +import ProxyGuideOverview from '../_proxy_guide_overview.mdx'; +import ProxyGuideTLSMode from '../_proxy_guide_tls_mode.mdx'; +import Compose from "!!raw-loader!./docker-compose.yaml"; +import ConfigDisabled from "!!raw-loader!./httpd-disabled-tls.conf"; +import ConfigExternal from "!!raw-loader!./httpd-external-tls.conf"; +import ConfigEnabled from "!!raw-loader!./httpd-enabled-tls.conf"; + +export const providername = "Apache httpd"; +export const lower = "httpd"; +export const link = {providername} + + + +You can either setup your environment for TLS mode disabled, TLS mode external or TLS mode enabled. + +## TLS mode disabled + + + + +## TLS mode external + + + + +## TLS mode enabled + + + + +## 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 new file mode 100644 index 000000000..99b47219c --- /dev/null +++ b/docs/docs/self-hosting/manage/reverseproxy/nginx/docker-compose.yaml @@ -0,0 +1,37 @@ +version: '3.8' + +services: + + proxy-disabled-tls: + image: "nginx:1.25.3-alpine" + volumes: + - "./nginx-disabled-tls.conf:/etc/nginx/nginx.conf:ro" + ports: + - "80:80" + depends_on: + zitadel-disabled-tls: + condition: 'service_healthy' + + proxy-external-tls: + image: "nginx:1.25.3-alpine" + volumes: + - "./nginx-external-tls.conf:/etc/nginx/nginx.conf:ro" + - "./selfsigned.crt:/etc/certs/selfsigned.crt:ro" + - "./selfsigned.key:/etc/certs/selfsigned.key:ro" + ports: + - "443:443" + depends_on: + zitadel-external-tls: + condition: 'service_healthy' + + proxy-enabled-tls: + image: "nginx:1.25.3-alpine" + volumes: + - "./nginx-enabled-tls.conf:/etc/nginx/nginx.conf:ro" + - "./selfsigned.crt:/etc/certs/selfsigned.crt:ro" + - "./selfsigned.key:/etc/certs/selfsigned.key:ro" + ports: + - "443:443" + depends_on: + zitadel-enabled-tls: + condition: 'service_healthy' 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 new file mode 100644 index 000000000..1ea55b990 --- /dev/null +++ b/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx-disabled-tls.conf @@ -0,0 +1,13 @@ +events { + worker_connections 1024; +} +http { + server { + listen 80; + http2 on; + location / { + grpc_pass grpc://zitadel-disabled-tls:8080; + grpc_set_header Host $host:$server_port; + } + } +} 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 new file mode 100644 index 000000000..00e83f74a --- /dev/null +++ b/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx-enabled-tls.conf @@ -0,0 +1,15 @@ +events { + worker_connections 1024; +} +http { + server { + listen 443 ssl; + http2 on; + ssl_certificate /etc/certs/selfsigned.crt; + ssl_certificate_key /etc/certs/selfsigned.key; + location / { + grpc_pass grpcs://zitadel-enabled-tls:8080; + grpc_set_header Host $host:$server_port; + } + } +} 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 new file mode 100644 index 000000000..c2f34062c --- /dev/null +++ b/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx-external-tls.conf @@ -0,0 +1,15 @@ +events { + worker_connections 1024; +} +http { + server { + listen 443 ssl; + http2 on; + ssl_certificate /etc/certs/selfsigned.crt; + ssl_certificate_key /etc/certs/selfsigned.key; + location / { + grpc_pass grpc://zitadel-external-tls:8080; + grpc_set_header Host $host:$server_port; + } + } +} diff --git a/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx.mdx b/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx.mdx new file mode 100644 index 000000000..d05296a95 --- /dev/null +++ b/docs/docs/self-hosting/manage/reverseproxy/nginx/nginx.mdx @@ -0,0 +1,35 @@ +--- +title: Configure ZITADEL with NGINX +sidebar_label: NGINX +--- + +import ProxyGuideOverview from '../_proxy_guide_overview.mdx'; +import ProxyGuideTLSMode from '../_proxy_guide_tls_mode.mdx'; +import Compose from "!!raw-loader!./docker-compose.yaml"; +import ConfigDisabled from "!!raw-loader!./nginx-disabled-tls.conf"; +import ConfigExternal from "!!raw-loader!./nginx-external-tls.conf"; +import ConfigEnabled from "!!raw-loader!./nginx-enabled-tls.conf"; + +export const providername = 'NGINX'; +export const lower = "nginx"; +export const link = {providername}; + + + +You can either setup your environment for TLS mode disabled, TLS mode external or TLS mode enabled. + +## TLS mode disabled + + + +## TLS mode external + + + +## TLS mode enabled + + + +## More Information + + diff --git a/docs/docs/self-hosting/manage/reverseproxy/reverse_proxy.mdx b/docs/docs/self-hosting/manage/reverseproxy/reverse_proxy.mdx index c94c4cdcd..b37ef3123 100644 --- a/docs/docs/self-hosting/manage/reverseproxy/reverse_proxy.mdx +++ b/docs/docs/self-hosting/manage/reverseproxy/reverse_proxy.mdx @@ -2,58 +2,13 @@ title: Reverse Proxy Configuration --- -import Tabs from "@theme/Tabs"; -import TabItem from "@theme/TabItem"; -import Zcloud from "./_zitadel_cloud.mdx"; -import Nginx from "./_nginx.mdx"; -import Traefik from "./_traefik.mdx"; -import Caddy from "./_caddy.mdx"; -import Httpd from "./_httpd.mdx"; -import Cftunnel from "./_cloudflare_tunnel.mdx"; -import Cloudflare from "./_cloudflare.mdx"; -import More from "./_more.mdx"; +Check out one of the following guides to configure your favorite reverse proxy: -# Proxy Configuration +- [Traefik](/self-hosting/manage/reverseproxy/traefik) +- [NGINX](/self-hosting/manage/reverseproxy/nginx) +- [Caddy](/self-hosting/manage/reverseproxy/caddy) + +- [Cloudflare](/self-hosting/manage/reverseproxy/cloudflare) +- [Cloudflare Tunnel](/self-hosting/manage/reverseproxy/cloudflare_tunnel) +- [Fronting ZITADEL Cloud](/self-hosting/manage/reverseproxy/zitadel_cloud) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/docs/self-hosting/manage/reverseproxy/traefik/docker-compose.yaml b/docs/docs/self-hosting/manage/reverseproxy/traefik/docker-compose.yaml new file mode 100644 index 000000000..3082e95d2 --- /dev/null +++ b/docs/docs/self-hosting/manage/reverseproxy/traefik/docker-compose.yaml @@ -0,0 +1,37 @@ +version: '3.8' + +services: + + proxy-disabled-tls: + image: "traefik:v2.10.5" + volumes: + - "./traefik-disabled-tls.yaml:/etc/traefik/traefik.yaml:ro" + ports: + - "80:80" + depends_on: + zitadel-disabled-tls: + condition: 'service_healthy' + + proxy-external-tls: + image: "traefik:v2.10.5" + volumes: + - "./traefik-external-tls.yaml:/etc/traefik/traefik.yaml:ro" + - "./selfsigned.crt:/etc/certs/selfsigned.crt:ro" + - "./selfsigned.key:/etc/certs/selfsigned.key:ro" + ports: + - "443:443" + depends_on: + zitadel-external-tls: + condition: 'service_healthy' + + proxy-enabled-tls: + image: "traefik:v2.10.5" + volumes: + - "./traefik-enabled-tls.yaml:/etc/traefik/traefik.yaml:ro" + - "./selfsigned.crt:/etc/certs/selfsigned.crt:ro" + - "./selfsigned.key:/etc/certs/selfsigned.key:ro" + ports: + - "443:443" + depends_on: + zitadel-enabled-tls: + condition: 'service_healthy' 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 new file mode 100644 index 000000000..0dbf906fa --- /dev/null +++ b/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik-disabled-tls.yaml @@ -0,0 +1,20 @@ +log: + level: "DEBUG" +providers: + file: + filename: "/etc/traefik/traefik.yaml" +entrypoints: + web: + address: ":80" +http: + routers: + router: + entryPoints: + - "web" + service: "zitadel" + rule: 'PathPrefix(`/`)' + services: + zitadel: + loadBalancer: + servers: + - url: "h2c://zitadel-disabled-tls:8080" 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 new file mode 100644 index 000000000..b175d53a8 --- /dev/null +++ b/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik-enabled-tls.yaml @@ -0,0 +1,31 @@ +log: + level: "DEBUG" +providers: + file: + filename: "/etc/traefik/traefik.yaml" +entrypoints: + web: + address: ":443" +http: + routers: + router: + entryPoints: + - "web" + service: "zitadel" + rule: 'PathPrefix(`/`)' + tls: {} + services: + zitadel: + loadBalancer: + serversTransport: "zitadel" + servers: + - url: "https://zitadel-enabled-tls:8080" + serversTransports: + zitadel: + insecureSkipVerify: true +tls: + stores: + default: + defaultCertificate: + certFile: /etc/certs/selfsigned.crt + keyFile: /etc/certs/selfsigned.key 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 new file mode 100644 index 000000000..e91059036 --- /dev/null +++ b/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik-external-tls.yaml @@ -0,0 +1,27 @@ +log: + level: "DEBUG" +providers: + file: + filename: "/etc/traefik/traefik.yaml" +entrypoints: + web: + address: ":443" +http: + routers: + router: + entryPoints: + - "web" + service: "zitadel" + rule: 'PathPrefix(`/`)' + tls: {} + services: + zitadel: + loadBalancer: + servers: + - url: "h2c://zitadel-external-tls:8080" +tls: + stores: + default: + defaultCertificate: + certFile: /etc/certs/selfsigned.crt + keyFile: /etc/certs/selfsigned.key diff --git a/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik.mdx b/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik.mdx new file mode 100644 index 000000000..d9d1d78f5 --- /dev/null +++ b/docs/docs/self-hosting/manage/reverseproxy/traefik/traefik.mdx @@ -0,0 +1,35 @@ +--- +title: Configure ZITADEL with Traefik +sidebar_label: Traefik +--- + +import ProxyGuideOverview from '../_proxy_guide_overview.mdx'; +import ProxyGuideTLSMode from '../_proxy_guide_tls_mode.mdx'; +import Compose from "!!raw-loader!./docker-compose.yaml"; +import ConfigDisabled from "!!raw-loader!./traefik-disabled-tls.yaml"; +import ConfigExternal from "!!raw-loader!./traefik-external-tls.yaml"; +import ConfigEnabled from "!!raw-loader!./traefik-enabled-tls.yaml"; + +export const providername = 'Traefik'; +export const lower = "traefik"; +export const link = {providername}; + + + +You can either setup your environment for TLS mode disabled, TLS mode external or TLS mode enabled. + +## TLS mode disabled + + + +## TLS mode external + + + +## TLS mode enabled + + + +## More Information + + diff --git a/docs/docs/self-hosting/manage/reverseproxy/_zitadel_cloud.mdx b/docs/docs/self-hosting/manage/reverseproxy/zitadel_cloud/zitadel_cloud.mdx similarity index 85% rename from docs/docs/self-hosting/manage/reverseproxy/_zitadel_cloud.mdx rename to docs/docs/self-hosting/manage/reverseproxy/zitadel_cloud/zitadel_cloud.mdx index 706393651..1cbba5b3b 100644 --- a/docs/docs/self-hosting/manage/reverseproxy/_zitadel_cloud.mdx +++ b/docs/docs/self-hosting/manage/reverseproxy/zitadel_cloud/zitadel_cloud.mdx @@ -1,3 +1,8 @@ +--- +title: Front ZITADEL Cloud with a CDN, WAF or Reverse Proxy +sidebar_label: Fronting ZITADEL Cloud +--- + ## Fronting ZITADEL Cloud You can use your reverseproxy, content delivery network (CDN) or web application firewall (WAF) to front ZITADEL Cloud. diff --git a/docs/docs/self-hosting/manage/tls_modes.mdx b/docs/docs/self-hosting/manage/tls_modes.mdx index dc34dca07..c77b02272 100644 --- a/docs/docs/self-hosting/manage/tls_modes.mdx +++ b/docs/docs/self-hosting/manage/tls_modes.mdx @@ -2,8 +2,8 @@ title: TLS Modes --- -To allow ZITADEL to be run on any kind of infrastructure it allows to configure on how tho handle TLS connections. -There are three mode of operation: `external`, `enabled`, `disabled`. +To run ZITADEL on any kind of infrastructure, you can configure on how to handle TLS connections. +There are three modes of operation: `disabled`, `external`, `enabled`. Generally this command is set as argument while starting ZITADEL. For example like this: @@ -11,6 +11,16 @@ Generally this command is set as argument while starting ZITADEL. For example li zitadel start-from-init --masterkey "MasterkeyNeedsToHave32Characters" --tlsMode disabled ``` +## Disabled + +With the mode `disabled`, you instruct ZITADEL to await all connections with plain http without TLS. + +:::caution + +Be aware this is not a secure setup and should only be used for test systems! + +::: + ## External The mode `external` allows you to configure ZITADEL in such a way that it will instruct its clients to use https. @@ -19,8 +29,8 @@ However ZITADEL delegates the management of TLS connections to a reverseproxy, w ## Enabled When using the mode `enabled` ZITADEL is setup to await incoming connections in an encrypted fashion. -Wether it is from a client directly, a reverseproxy or web application firewall. -This allows http connections to be secured at the transport level the whole way. +Whether it is from a client directly, a reverse proxy or web application firewall. +This allows HTTP connections to be secured at the transport level the whole way. If you use the mode `enabled` you need to configure ZITADEL with the necessary TLS settings. @@ -42,17 +52,10 @@ TLS: Cert: # ``` -## Disabled +## More Information -With the mode `disabled` ZITADEL is instructed to await all connections with plain http without TLS. +Beware that ZITADEL uses HTTP/2 for all its connections. +If you are using the mode `external` or `disabled` make sure to verify h2c compatibility. -:::caution - -Be aware this is not a secure setup and should only be used for test systems! - -::: - -## HTTP/2 - -To allow ZITADEL to function properly please make sure that HTTP/2 is enabled. If you are using the mode `external` or `disabled` make sure to verify h2c compatibilty. -You can read more about how ZITADEL utilizes in our [HTTP/2 docs](/self-hosting/manage/http2). +- [Read more abouth how ZITADEL utilizes HTTP/2](/self-hosting/manage/http2). +- [Explore some concrete proxy configuration examples for ZITADEL](/self-hosting/manage/reverseproxy/reverse_proxy). diff --git a/docs/docs/self-hosting/manage/updating_scaling.md b/docs/docs/self-hosting/manage/updating_scaling.md index 66cd502f3..7addca0b0 100644 --- a/docs/docs/self-hosting/manage/updating_scaling.md +++ b/docs/docs/self-hosting/manage/updating_scaling.md @@ -61,6 +61,8 @@ ZITADEL uses the privileged and preexisting database user configured in `Databas - If not already done, it grants the necessary permissions ZITADEL needs to the non privileged user. - If they don’t exist already, it creates all schemas and some basic tables. +The init phase is idempotent if executed with the same binary version. + ### The Setup Phase During `zitadel setup`, ZITADEL creates projection tables and migrates existing data. @@ -70,7 +72,10 @@ When deploying a new ZITADEL version, make sure the setup phase runs before you roll out the new `zitadel start` processes. The setup phase is executed in subsequent steps whereas a new version's execution takes over where the last execution stopped. -Therefore, configuration changes relevant for the setup phase won’t take effect in regard to the setup execution. + +Some configuration changes are only applied during the setup phase, like ExternalDomain, ExternalPort and ExternalSecure. + +The setup phase is idempotent if executed with the same binary version. ### The Runtime Phase diff --git a/docs/sidebars.js b/docs/sidebars.js index 10c5e8796..14775e216 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -658,7 +658,24 @@ module.exports = { "self-hosting/manage/production", "self-hosting/manage/productionchecklist", "self-hosting/manage/configure/configure", - "self-hosting/manage/reverseproxy/reverse_proxy", + { + type: "category", + collapsed: false, + label: "Reverse Proxy", + link: { + type: "doc", + id: "self-hosting/manage/reverseproxy/reverse_proxy", + }, + items: [ + "self-hosting/manage/reverseproxy/traefik/traefik", + "self-hosting/manage/reverseproxy/nginx/nginx", + "self-hosting/manage/reverseproxy/caddy/caddy", +// "self-hosting/manage/reverseproxy/httpd/httpd", grpc NOT WORKING + "self-hosting/manage/reverseproxy/cloudflare/cloudflare", + "self-hosting/manage/reverseproxy/cloudflare_tunnel/cloudflare_tunnel", + "self-hosting/manage/reverseproxy/zitadel_cloud/zitadel_cloud", + ], + }, "self-hosting/manage/custom-domain", "self-hosting/manage/http2", "self-hosting/manage/tls_modes", diff --git a/e2e/config/localhost/docker-compose.yaml b/e2e/config/localhost/docker-compose.yaml index 7001cfb32..7ec0f28c5 100644 --- a/e2e/config/localhost/docker-compose.yaml +++ b/e2e/config/localhost/docker-compose.yaml @@ -22,7 +22,7 @@ services: ports: - "8080:8080" healthcheck: - test: ["CMD", "/app/zitadel", "ready"] + test: ["CMD", "/app/zitadel", "ready", "--config", "/zitadel.yaml" ] interval: '10s' timeout: '5s' retries: 5 diff --git a/internal/api/api.go b/internal/api/api.go index aaa3cd66d..82d574fe0 100644 --- a/internal/api/api.go +++ b/internal/api/api.go @@ -63,7 +63,7 @@ func New( } api.grpcServer = server.CreateServer(api.verifier, authZ, queries, http2HostName, tlsConfig, accessInterceptor.AccessService()) - api.grpcGateway, err = server.CreateGateway(ctx, port, http1HostName, accessInterceptor) + api.grpcGateway, err = server.CreateGateway(ctx, port, http1HostName, accessInterceptor, tlsConfig) if err != nil { return nil, err } @@ -80,7 +80,7 @@ func New( // creates a new grpc gateway and registers it as a separate http handler // // used for v1 api (system, admin, mgmt, auth) -func (a *API) RegisterServer(ctx context.Context, grpcServer server.WithGatewayPrefix) error { +func (a *API) RegisterServer(ctx context.Context, grpcServer server.WithGatewayPrefix, tlsConfig *tls.Config) error { grpcServer.RegisterServer(a.grpcServer) handler, prefix, err := server.CreateGatewayWithPrefix( ctx, @@ -89,6 +89,7 @@ func (a *API) RegisterServer(ctx context.Context, grpcServer server.WithGatewayP a.http1HostName, a.accessInterceptor, a.queries, + tlsConfig, ) if err != nil { return err diff --git a/internal/api/grpc/server/gateway.go b/internal/api/grpc/server/gateway.go index dc69ec75e..6c506ea34 100644 --- a/internal/api/grpc/server/gateway.go +++ b/internal/api/grpc/server/gateway.go @@ -2,6 +2,7 @@ package server import ( "context" + "crypto/tls" "fmt" "net/http" "strings" @@ -9,6 +10,7 @@ import ( "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/zitadel/logging" "google.golang.org/grpc" + "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" healthpb "google.golang.org/grpc/health/grpc_health_v1" "google.golang.org/protobuf/encoding/protojson" @@ -89,10 +91,11 @@ func CreateGatewayWithPrefix( http1HostName string, accessInterceptor *http_mw.AccessInterceptor, queries *query.Queries, + tlsConfig *tls.Config, ) (http.Handler, string, error) { runtimeMux := runtime.NewServeMux(serveMuxOptions...) opts := []grpc.DialOption{ - grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithTransportCredentials(grpcCredentials(tlsConfig)), grpc.WithUnaryInterceptor(client_middleware.DefaultTracingClient()), } connection, err := dial(ctx, port, opts) @@ -106,11 +109,17 @@ func CreateGatewayWithPrefix( return addInterceptors(runtimeMux, http1HostName, accessInterceptor, queries), g.GatewayPathPrefix(), nil } -func CreateGateway(ctx context.Context, port uint16, http1HostName string, accessInterceptor *http_mw.AccessInterceptor) (*Gateway, error) { +func CreateGateway( + ctx context.Context, + port uint16, + http1HostName string, + accessInterceptor *http_mw.AccessInterceptor, + tlsConfig *tls.Config, +) (*Gateway, error) { connection, err := dial(ctx, port, []grpc.DialOption{ - grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithTransportCredentials(grpcCredentials(tlsConfig)), grpc.WithUnaryInterceptor(client_middleware.DefaultTracingClient()), }) if err != nil { @@ -217,3 +226,15 @@ func (r *cookieResponseWriter) WriteHeader(status int) { } r.ResponseWriter.WriteHeader(status) } + +func grpcCredentials(tlsConfig *tls.Config) credentials.TransportCredentials { + creds := insecure.NewCredentials() + if tlsConfig != nil { + tlsConfigClone := tlsConfig.Clone() + // We don't want to verify the certificate of the internal grpc server + // That's up to the client who called the gRPC gateway + tlsConfigClone.InsecureSkipVerify = true + creds = credentials.NewTLS(tlsConfigClone) + } + return creds +} diff --git a/internal/static/i18n/bg.yaml b/internal/static/i18n/bg.yaml index 46eda0c4d..835abf24d 100644 --- a/internal/static/i18n/bg.yaml +++ b/internal/static/i18n/bg.yaml @@ -319,7 +319,7 @@ Errors: NotActive: Грантът по проекта не е активен NotInactive: Грантът по проекта не е неактивен IAM: - NotFound: Екземплярът не е намерен + NotFound: Екземплярът не е намерен. Вижте https://zitadel.com/docs/self-hosting/manage/custom-domain Member: RolesNotChanged: Ролите не са сменени MemberInvalid: Членът е невалиден diff --git a/internal/static/i18n/cs.yaml b/internal/static/i18n/cs.yaml index ffa77c00f..f18148b7b 100644 --- a/internal/static/i18n/cs.yaml +++ b/internal/static/i18n/cs.yaml @@ -317,7 +317,7 @@ Errors: NotActive: Grant projektu není aktivní NotInactive: Grant projektu není neaktivní IAM: - NotFound: Instance nenalezena + NotFound: Instance nenalezena. Podívejte se na https://zitadel.com/docs/self-hosting/manage/custom-domain Member: RolesNotChanged: Role nebyly změněny MemberInvalid: Člen je neplatný diff --git a/internal/static/i18n/de.yaml b/internal/static/i18n/de.yaml index 0b902da86..051a925e5 100644 --- a/internal/static/i18n/de.yaml +++ b/internal/static/i18n/de.yaml @@ -317,7 +317,7 @@ Errors: NotActive: Projekt Grant ist nicht aktiv NotInactive: Projekt Grant ist nicht inaktiv IAM: - NotFound: Instanz nicht gefunden + NotFound: Instanz nicht gefunden. Schau dir https://zitadel.com/docs/self-hosting/manage/custom-domain an Member: RolesNotChanged: Rollen wurden nicht verändert MemberInvalid: Member ist ungültig diff --git a/internal/static/i18n/en.yaml b/internal/static/i18n/en.yaml index ed881e22a..63aa8a8fb 100644 --- a/internal/static/i18n/en.yaml +++ b/internal/static/i18n/en.yaml @@ -317,7 +317,7 @@ Errors: NotActive: Project grant is not active NotInactive: Project grant is not inactive IAM: - NotFound: Instance not found + NotFound: Instance not found. Check out https://zitadel.com/docs/self-hosting/manage/custom-domain Member: RolesNotChanged: Roles have not been changed MemberInvalid: Member is invalid diff --git a/internal/static/i18n/es.yaml b/internal/static/i18n/es.yaml index ff4410cb0..9a1a1ff82 100644 --- a/internal/static/i18n/es.yaml +++ b/internal/static/i18n/es.yaml @@ -317,7 +317,7 @@ Errors: NotActive: La concesión del proyecto no está activa NotInactive: La concesión del proyecto no está inactiva IAM: - NotFound: Instancia no encontrada + NotFound: Instancia no encontrada. Consulta https://zitadel.com/docs/self-hosting/manage/custom-domain Member: RolesNotChanged: Los roles no han cambiado MemberInvalid: El miembro no es válido diff --git a/internal/static/i18n/fr.yaml b/internal/static/i18n/fr.yaml index 3a14c5226..fbd6c2c13 100644 --- a/internal/static/i18n/fr.yaml +++ b/internal/static/i18n/fr.yaml @@ -317,7 +317,7 @@ Errors: NotActive: La subvention de projet n'est pas active NotInactive: La subvention du projet n'est pas inactive IAM: - NotFound: Instance non trouvée + NotFound: Instance non trouvée. Consultez https://zitadel.com/docs/self-hosting/manage/custom-domain Member: RolesNotChanged: Les rôles n'ont pas été modifiés MemberInvalid: Le membre n'est pas valide diff --git a/internal/static/i18n/it.yaml b/internal/static/i18n/it.yaml index fe56c424e..b451d370b 100644 --- a/internal/static/i18n/it.yaml +++ b/internal/static/i18n/it.yaml @@ -318,7 +318,7 @@ Errors: NotActive: Grant del progetto non è attivo NotInactive: Grant del progetto non è inattivo IAM: - NotFound: Istanza non trovata + NotFound: Istanza non trovata. Controlla https://zitadel.com/docs/self-hosting/manage/custom-domain Member: RolesNotChanged: I ruoli non sono stati cambiati MemberInvalid: Il membro non è valido diff --git a/internal/static/i18n/ja.yaml b/internal/static/i18n/ja.yaml index 9180e41d5..ec037a7a8 100644 --- a/internal/static/i18n/ja.yaml +++ b/internal/static/i18n/ja.yaml @@ -306,7 +306,7 @@ Errors: NotActive: プロジェクトグラントはアクティブではありません NotInactive: プロジェクトグラントは非アクティブではありません IAM: - NotFound: インスタンスが見つかりません + NotFound: インスタンスが見つかりません https://zitadel.com/docs/self-hosting/manage/custom-domain Member: RolesNotChanged: ロールは変更されていません MemberInvalid: 無効なメンバーです diff --git a/internal/static/i18n/mk.yaml b/internal/static/i18n/mk.yaml index 085daec0d..51dde7467 100644 --- a/internal/static/i18n/mk.yaml +++ b/internal/static/i18n/mk.yaml @@ -317,7 +317,7 @@ Errors: NotActive: Овластувањето за проектот не е активно NotInactive: Овластувањето за проектот не е неактивно IAM: - NotFound: Инстанцата не е пронајдена + NotFound: Инстанцата не е пронајдена. Проверете https://zitadel.com/docs/self-hosting/manage/custom-domain Member: RolesNotChanged: Улогите не се променети MemberInvalid: Членот е невалиден diff --git a/internal/static/i18n/pl.yaml b/internal/static/i18n/pl.yaml index 3a54a6fcb..bb7dc3442 100644 --- a/internal/static/i18n/pl.yaml +++ b/internal/static/i18n/pl.yaml @@ -317,7 +317,7 @@ Errors: NotActive: Grant projektu jest nieaktywny NotInactive: Grant projektu nie jest nieaktywny IAM: - NotFound: Instancja nie znaleziona + NotFound: Instancja nie znaleziona. Sprawdź https://zitadel.com/docs/self-hosting/manage/custom-domain Member: RolesNotChanged: Role nie zmienione MemberInvalid: Członek jest nieprawidłowy diff --git a/internal/static/i18n/pt.yaml b/internal/static/i18n/pt.yaml index 90ff628a1..472a7b5bd 100644 --- a/internal/static/i18n/pt.yaml +++ b/internal/static/i18n/pt.yaml @@ -315,7 +315,7 @@ Errors: NotActive: A concessão do projeto não está ativa NotInactive: A concessão do projeto não está inativa IAM: - NotFound: Instância não encontrada + NotFound: Instância não encontrada. Confira https://zitadel.com/docs/self-hosting/manage/custom-domain Member: RolesNotChanged: As funções não foram alteradas MemberInvalid: O membro é inválido diff --git a/internal/static/i18n/ru.yaml b/internal/static/i18n/ru.yaml index fa053b319..2b89e5cbe 100644 --- a/internal/static/i18n/ru.yaml +++ b/internal/static/i18n/ru.yaml @@ -308,7 +308,7 @@ Errors: NotActive: Грант проекта не активен NotInactive: Грант проекта не неактивен IAM: - NotFound: Экземпляр не найден + NotFound: Экземпляр не найден. Проверьте https://zitadel.com/docs/self-hosting/manage/custom-domain Member: RolesNotChanged: Роли не изменились MemberInvalid: Участник недействителен diff --git a/internal/static/i18n/zh.yaml b/internal/static/i18n/zh.yaml index a44de5485..4a2379823 100644 --- a/internal/static/i18n/zh.yaml +++ b/internal/static/i18n/zh.yaml @@ -317,7 +317,7 @@ Errors: NotActive: 项目授权不是启用状态 NotInactive: 项目授权不是停用状态 IAM: - NotFound: 实例未找到 + NotFound: 实例未找到。查看 https://zitadel.com/docs/self-hosting/manage/custom-domain Member: RolesNotChanged: 角色没有改变 MemberInvalid: 成员无效