diff --git a/docs/guides/server/hostname-deprecated.adoc b/docs/guides/server/hostname-deprecated.adoc new file mode 100644 index 000000000000..2488dd2804c6 --- /dev/null +++ b/docs/guides/server/hostname-deprecated.adoc @@ -0,0 +1,158 @@ +<#import "/templates/guide.adoc" as tmpl> +<#import "/templates/kc.adoc" as kc> +<#import "/templates/links.adoc" as links> + +<@tmpl.guide +title="Configuring the hostname (v1)" +summary="Learn how to configure the frontend and backchannel endpoints exposed by {project_name}." +includedOptions="hostname hostname-* proxy" +deniedCategories="hostname_v2"> + +WARNING: The hostname configuration options used in this guide are deprecated and will be removed in a future release. Therefore, it is recommended to use the new hostname configuration options. For more details, see <@links.server id="hostname"/> guide. + +== Server Endpoints + +{project_name} exposes different endpoints to talk with applications and allow access to the administration console. These endpoints +can be categorized into three main groups: + +* Frontend +* Backend +* Administration Console + +The base URL for each group has an important impact on how tokens are issued and validated, on how links are created for actions that require the user +to be redirected to {project_name} (for example, when resetting password through email links), and, most importantly, how applications will +discover these endpoints when fetching the OpenID Connect Discovery Document from `realms/++{realm-name}++/.well-known/openid-configuration`. + +=== Frontend + +The frontend endpoints are those accessible through a public domain and usually related to authentication/authorization flows that happen +through the front-channel. For instance, when an SPA wants to authenticate their users it redirects them to the `authorization_endpoint` so that users +can authenticate using their browsers through the front-channel. + +By default, when the hostname settings are not set, the base URL for these endpoints is based on the incoming request so that the HTTP scheme, +host, port, and path, are the same from the request. The default behavior also has a direct impact on how the server is going to issue tokens given that the issuer is also based on +the URL set to the frontend endpoints. If the hostname settings are not set, the token issuer will also be based on the incoming request and also lack consistency if the client is requesting tokens using different URLs. + +When deploying to production you usually want a consistent URL for the frontend endpoints and the token issuer regardless of how the request is constructed. +In order to achieve this consistency, you can set either the `hostname` or the `hostname-url` options. + +Most of the time, it should be enough to set the `hostname` option in order to change only the *host* of the frontend URLs: + +<@kc.start parameters="--hostname="/> + +When using the `hostname` option the server is going to resolve the HTTP scheme, port, and path, automatically so that: + +* `https` scheme is used unless you set `hostname-strict-https=false` +* if the `proxy-headers` option is set, the proxy will use the default ports (i.e.: 80 and 443). If the proxy uses a different port, it needs to be specified via the `hostname-url` configuration option + +However, if you want to set not only the host but also a scheme, port, and path, you can set the `hostname-url` option: + +<@kc.start parameters="--hostname-url=://:/"/> + +This option gives you more flexibility as you can set the different parts of the URL from a single option. Note that +the `hostname` and `hostname-url` are mutually exclusive. + +[NOTE] +==== +By `hostname` and `proxy-headers` configuration options you affect only the static resources URLs, redirect URIs, OIDC well-known endpoints, etc. In order to change, where/on which port the server actually listens on, you need to use the `http/tls` configuration options (e.g. `http-host`, `https-port`, etc.). For more details, see <@links.server id="enabletls"/> and <@links.server id="all-config"/>. +==== + +=== Backend + +The backend endpoints are those accessible through a public domain or through a private network. They are used for a direct communication +between the server and clients without any intermediary but plain HTTP requests. For instance, after the user is authenticated an SPA +wants to exchange the `code` sent by the server with a set of tokens by sending a token request to `token_endpoint`. + +By default, the URLs for backend endpoints are also based on the incoming request. To override this behavior, set the `hostname-strict-backchannel` configuration option by entering this command: + +<@kc.start parameters="--hostname= --hostname-strict-backchannel=true"/> + +By setting the `hostname-strict-backchannel` option, the URLs for the backend endpoints are going to be exactly the same as the frontend endpoints. + +When all applications connected to {project_name} communicate through the public URL, set `hostname-strict-backchannel` to `true`. +Otherwise, leave this parameter as `false` to allow client-server communication through a private network. + +=== Administration Console + +The server exposes the administration console and static resources using a specific URL. + +By default, the URLs for the administration console are also based on the incoming request. However, you can set a specific host or base URL if you want +to restrict access to the administration console using a specific URL. Similarly to how you set the frontend URLs, you can use the `hostname-admin` and `hostname-admin-url` options to achieve that. +Note that if HTTPS is enabled (`http-enabled` configuration option is set to false, which is the default setting for the production mode), the {project_name} server automatically assumes you want to use HTTPS URLs. The admin console then tries to contact {project_name} over HTTPS and HTTPS URLs are also used for its configured redirect/web origin URLs. It is not recommended for production, but you can use HTTP URL as `hostname-admin-url` to override this behaviour. + +Most of the time, it should be enough to set the `hostname-admin` option in order to change only the *host* of the administration console URLs: + +<@kc.start parameters="--hostname-admin="/> + +However, if you want to set not only the host but also a scheme, port, and path, you can set the `hostname-admin-url` option: + +<@kc.start parameters="--hostname-admin-url=://:/"/> + +Note that the `hostname-admin` and `hostname-admin-url` are mutually exclusive. + +To reduce attack surface, the administration endpoints for {project_name} and the Admin Console should not be publicly accessible. +Therefore, you can secure them by using a reverse proxy. +For more information about which paths to expose using a reverse proxy, see <@links.server id="reverseproxy"/>. + +== Example Scenarios +The following are more example scenarios and the corresponding commands for setting up a hostname. + +Note that the `start` command requires setting up TLS. The corresponding options are not shown for example purposes. For more details, see <@links.server id="enabletls"/>. + +=== Exposing the server behind a TLS termination proxy + +In this example, the server is running behind a TLS termination proxy and publicly available from `https://mykeycloak`. + +.Configuration: +<@kc.start parameters="--hostname=mykeycloak --http-enabled=true --proxy-headers=forwarded|xforwarded"/> + +=== Exposing the server without a proxy + +In this example, the server is running without a proxy and exposed using a URL using HTTPS. + +.{project_name} configuration: +<@kc.start parameters="--hostname-url=https://mykeycloak"/> + +It is highly recommended using a TLS termination proxy in front of the server for security and availability reasons. For more details, +see <@links.server id="reverseproxy"/>. + +=== Forcing backend endpoints to use the same URL the server is exposed + +In this example, backend endpoints are exposed using the same URL used by the server so that clients always fetch the same URL +regardless of the origin of the request. + +.{project_name} configuration: +<@kc.start parameters="--hostname=mykeycloak --hostname-strict-backchannel=true"/> + +=== Exposing the server using a port other than the default ports + +In this example, the server is accessible using a port other than the default ports. + +.{project_name} configuration: +<@kc.start parameters="--hostname-url=https://mykeycloak:8989"/> + +=== Exposing {project_name} behind a TLS reencrypt proxy using different ports + +In this example, the server is running behind a proxy and both the server and the proxy are using their own certificates, so the communication between {project_name} and the proxy is encrypted. The reverse proxy uses the `Forwarded` header and does not set the `X-Forwarded-*` headers. We need to keep in mind that the proxy configuration options (as well as hostname configuration options) are not changing the ports on which the server actually is listening on (it changes only the ports of static resources like JavaScript and CSS links, OIDC well-known endpoints, redirect URIs, etc.). Therefore, we need to use HTTP configuration options to change the {project_name} server to internally listen on a different port, e.g. 8543. The proxy will be listening on the port 8443 (the port visible while accessing the console via a browser). The example hostname `my-keycloak.org` will be used for the server and similarly the admin console will be accessible via the `admin.my-keycloak.org` subdomain. + +.{project_name} configuration: +<@kc.start parameters="--proxy-headers=forwarded --https-port=8543 --hostname-url=https://my-keycloak.org:8443 --hostname-admin-url=https://admin.my-keycloak.org:8443"/> + +WARNING: Usage of the `proxy-headers` option rely on `Forwarded` and `X-Forwarded-*` headers, respectively, that have to be set and overwritten by the reverse proxy. +Misconfiguration may leave {project_name} exposed to security issues. For more details, see <@links.server id="reverseproxy"/>. + +== Troubleshooting + +To troubleshoot the hostname configuration, you can use a dedicated debug tool which can be enabled as: + +.{project_name} configuration: +<@kc.start parameters="--hostname=mykeycloak --hostname-debug=true"/> + +Then after {project_name} started properly, open your browser and go to: + +`http://mykeycloak:8080/realms//hostname-debug` + +.By default, this endpoint is disabled (`--hostname-debug=false`) + + + diff --git a/docs/guides/server/hostname.adoc b/docs/guides/server/hostname.adoc index 3a3268dd64f2..b9d77409d3ff 100644 --- a/docs/guides/server/hostname.adoc +++ b/docs/guides/server/hostname.adoc @@ -3,141 +3,140 @@ <#import "/templates/links.adoc" as links> <@tmpl.guide -title="Configuring the hostname" +title="Configuring the hostname (v2)" summary="Learn how to configure the frontend and backchannel endpoints exposed by {project_name}." includedOptions="hostname hostname-* proxy" -deniedCategories="hostname_v2"> +deniedCategories="hostname_v1"> -== Server Endpoints +== The importance of setting the hostname option -{project_name} exposes different endpoints to talk with applications as well as to allow accessing the administration console. These endpoints -can be categorized into three main groups: +By default, {project_name} mandates the configuration of the `hostname` option and does not dynamically resolve URLs. This is a security measure. -* Frontend -* Backend -* Administration Console +{project_name} freely discloses its own URLs, for instance through the OIDC Discovery endpoint, or as part of the password reset link in an email. If the hostname was dynamically interpreted from a hostname header, it could provide a potential attacker with an opportunity to manipulate a URL in the email, redirect a user to the attacker's fake domain, and steal sensitive data such as action tokens, passwords, etc. -The base URL for each group has an important impact on how tokens are issued and validated, on how links are created for actions that require the user -to be redirected to {project_name} (for example, when resetting password through email links), and, most importantly, how applications will -discover these endpoints when fetching the OpenID Connect Discovery Document from `realms/++{realm-name}++/.well-known/openid-configuration`. +By explicitly setting the `hostname` option, we avoid a situation where tokens could be issued by a fraudulent issuer. The server can be started with an explicit hostname using the following command: -=== Frontend +<@kc.start parameters="--hostname my.keycloak.org"/> -The frontend endpoints are those accessible through a public domain and usually related to authentication/authorization flows that happen -through the front-channel. For instance, when an SPA wants to authenticate their users it redirects them to the `authorization_endpoint` so that users -can authenticate using their browsers through the front-channel. +NOTE: The examples start the {project_name} instance in production mode, which requires a public certificate and private key in order to secure communications. For more information, refer to the <@links.server id="configuration-production"/>. -By default, when the hostname settings are not set, the base URL for these endpoints is based on the incoming request so that the HTTP scheme, -host, port, and path, are the same from the request. The default behavior also has a direct impact on how the server is going to issue tokens given that the issuer is also based on -the URL set to the frontend endpoints. If the hostname settings are not set, the token issuer will also be based on the incoming request and also lack consistency if the client is requesting tokens using different URLs. +== Defining specific parts of the hostname option -When deploying to production you usually want a consistent URL for the frontend endpoints and the token issuer regardless of how the request is constructed. -In order to achieve this consistency, you can set either the `hostname` or the `hostname-url` options. +As demonstrated in the previous example, the scheme and port are not explicitly required. In such cases, {project_name} automatically handles these aspects. For instance, the server would be accessible at `https://my.keycloak.org:8443` in the given example. However, a reverse proxy will typically expose {project_name} at the default ports, e.g. `443`. In that case it’s desirable to specify the full URL in the `hostname` option rather than keeping the parts of the URL dynamic. The server can then be started with: -Most of the time, it should be enough to set the `hostname` option in order to change only the *host* of the frontend URLs: +<@kc.start parameters="--hostname https://my.keycloak.org"/> -<@kc.start parameters="--hostname="/> +Similarly, your reverse proxy might expose {project_name} at a different context path. It is possible to configure {proxy_name} to reflect that via the `hostname` and `hostname-admin` options. See the following example: -When using the `hostname` option the server is going to resolve the HTTP scheme, port, and path, automatically so that: +<@kc.start parameters="--hostname https://my.keycloak.org:123/auth"/> -* `https` scheme is used unless you set `hostname-strict-https=false` -* if the `proxy-headers` option is set, the proxy will use the default ports (i.e.: 80 and 443). If the proxy uses a different port, it needs to be specified via the `hostname-url` configuration option +== Utilizing an internal URL for communication among clients -However, if you want to set not only the host but also a scheme, port, and path, you can set the `hostname-url` option: +{project_name} has the capability to offer a separate URL for backchannel requests, enabling internal communication while maintaining the use of a public URL for frontchannel requests. Moreover, the backchannel is dynamically resolved based on incoming headers. Consider the following example: -<@kc.start parameters="--hostname-url=://:/"/> +<@kc.start parameters="--hostname https://my.keycloak.org --hostname-backchannel-dynamic true"/> -This option gives you more flexibility as you can set the different parts of the URL from a single option. Note that -the `hostname` and `hostname-url` are mutually exclusive. +In this manner, your applications, referred to as clients, can connect with {project_name} through your local network, while the server remains publicly accessible at `https://my.keycloak.org`. -[NOTE] -==== -By `hostname` and `proxy-headers` configuration options you affect only the static resources URLs, redirect URIs, OIDC well-known endpoints, etc. In order to change, where/on which port the server actually listens on, you need to use the `http/tls` configuration options (e.g. `http-host`, `https-port`, etc.). For more details, see <@links.server id="enabletls"/> and <@links.server id="all-config"/>. -==== +== Using edge TLS termination -=== Backend +As you can observe, the HTTPS protocol is the default choice, adhering to {project_name}'s commitment to security best practices. However, {project_name} also provides the flexibility for users to opt for HTTP if necessary. This can be achieved simply by specifying the HTTP listener, consult the <@links.server id="enabletls"/> for details. With an edge TLS-termination proxy you can start the server as follows: -The backend endpoints are those accessible through a public domain or through a private network. They are used for a direct communication -between the server and clients without any intermediary but plain HTTP requests. For instance, after the user is authenticated an SPA -wants to exchange the `code` sent by the server with a set of tokens by sending a token request to `token_endpoint`. +<@kc.start parameters="--hostname https://my.keycloak.org --http-enabled true"/> -By default, the URLs for backend endpoints are also based on the incoming request. To override this behavior, set the `hostname-strict-backchannel` configuration option by entering this command: +The result of this configuration is that you can continue to access {project_name} at `https://my.keycloak.org` via HTTPS, while the proxy interacts with the instance using HTTP and port `8080`. -<@kc.start parameters="--hostname= --hostname-strict-backchannel=true"/> +== Relying on a trusted proxy for the dynamic hostname resolution -By setting the `hostname-strict-backchannel` option, the URLs for the backend endpoints are going to be exactly the same as the frontend endpoints. +If you fully trust your proxy, which correctly sets the Forwarded header, and you don't want to hardcode the hostname, {project_name} can accommodate this. You simply need to initiate the server as follows: -When all applications connected to {project_name} communicate through the public URL, set `hostname-strict-backchannel` to `true`. -Otherwise, leave this parameter as `false` to allow client-server communication through a private network. +<@kc.start parameters="--hostname-strict false --proxy-headers forwarded"/> -=== Administration Console +With this configuration, the server respects the value set by the Forwarded header. This also implies that all endpoints are dynamically resolved. -The server exposes the administration console and static resources using a specific URL. +The `proxy-headers` option can be also used to resolve the URL partially dynamically when `hostname` option is not specified as a full URL. For example: -By default, the URLs for the administration console are also based on the incoming request. However, you can set a specific host or base URL if you want -to restrict access to the administration console using a specific URL. Similarly to how you set the frontend URLs, you can use the `hostname-admin` and `hostname-admin-url` options to achieve that. -Note that if HTTPS is enabled (`http-enabled` configuration option is set to false, which is the default setting for the production mode), the {project_name} server automatically assumes you want to use HTTPS URLs. The admin console then tries to contact {project_name} over HTTPS and HTTPS URLs are also used for its configured redirect/web origin URLs. It is not recommended for production, but you can use HTTP URL as `hostname-admin-url` to override this behaviour. +<@kc.start parameters="--hostname my.keycloak.org --proxy-headers xforwarded"/> -Most of the time, it should be enough to set the `hostname-admin` option in order to change only the *host* of the administration console URLs: +In this case, scheme, port and context path are resolved dynamically from X-Forwarded-* headers, while hostname is statically defined as `my.keycloak.org`. -<@kc.start parameters="--hostname-admin="/> +WARNING: If either `forwarded` or `xforwarded` is selected, make sure your reverse proxy properly sets and overwrites the `Forwarded` or `X-Forwarded-*` headers respectively. To set these headers, consult the documentation for your reverse proxy. Misconfiguration will leave {project_name} exposed to security vulnerabilities. -However, if you want to set not only the host but also a scheme, port, and path, you can set the `hostname-admin-url` option: +== Exposing the Administration Console on a separate hostname -<@kc.start parameters="--hostname-admin-url=://:/"/> +If you wish to expose the Admin Console on a different host, you can do so with the following command: -Note that the `hostname-admin` and `hostname-admin-url` are mutually exclusive. +<@kc.start parameters="--hostname https://my.keycloak.org --hostname-admin https://admin.my.keycloak.org:8443"/> -To reduce attack surface, the administration endpoints for {project_name} and the Admin Console should not be publicly accessible. -Therefore, you can secure them by using a reverse proxy. -For more information about which paths to expose using a reverse proxy, see <@links.server id="reverseproxy"/>. +This allows you to access {project_name} at `https://my.keycloak.org` and the Admin Console at `https://admin.my.keycloak.org:8443`, while the backend continues to use `https://my.keycloak.org`. -== Example Scenarios -The following are more example scenarios and the corresponding commands for setting up a hostname. -Note that the `start` command requires setting up TLS. The corresponding options are not shown for example purposes. For more details, see <@links.server id="enabletls"/>. +NOTE: Keep in mind that hostname and proxy options do not change the ports on which the server listens. Instead it changes only the ports of static resources like JavaScript and CSS links, OIDC well-known endpoints, redirect URIs, etc. that will be used in front of the proxy. You need to use HTTP configuration options to change the actual ports the server is listening on. Refer to the <@links.server id="all-config"/> for details. -=== Exposing the server behind a TLS termination proxy +== Background - server endpoints -In this example, the server is running behind a TLS termination proxy and publicly available from `https://mykeycloak`. +{project_name} exposes several endpoints, each with a different purpose. They are typically used for communication among applications or for managing the server. We recognize 3 main endpoint groups: -.Configuration: -<@kc.start parameters="--hostname=mykeycloak --http-enabled=true --proxy-headers=forwarded|xforwarded"/> +* Frontend +* Backend +* Administration -=== Exposing the server without a proxy +If you want to work with either of these endpoints, you need to set the base URL. The base URL consists of a several parts: -In this example, the server is running without a proxy and exposed using a URL using HTTPS. +* a scheme (e.g. https protocol) +* a hostname (e.g. example.keycloak.org) +* a port (e.g. 8443) +* a path (e.g. /auth) -.{project_name} configuration: -<@kc.start parameters="--hostname-url=https://mykeycloak"/> +The base URL for each group has an important impact on how tokens are issued and validated, on how links are created for actions that require the user to be redirected to {project_name} (for example, when resetting password through email links), and, most importantly, how applications will discover these endpoints when fetching the OpenID Connect Discovery Document from `realms/{realm-name}/.well-known/openid-configuration`. -It is highly recommended using a TLS termination proxy in front of the server for security and availability reasons. For more details, -see <@links.server id="reverseproxy"/>. +=== Frontend -=== Forcing backend endpoints to use the same URL the server is exposed +Users and applications use the frontend URL to access {project_name} through a front channel. The front channel is a publicly accessible communication channel. For example browser-based flows (accessing the login page, clicking on the link to reset a password or binding the tokens) can be considered as frontchannel requests. -In this example, backend endpoints are exposed using the same URL used by the server so that clients always fetch the same URL -regardless of the origin of the request. +In order to make {project_name} accessible via the frontend URL, you need to set the `hostname` option: -.{project_name} configuration: -<@kc.start parameters="--hostname=mykeycloak --hostname-strict-backchannel=true"/> +<@kc.start parameters="--hostname my.keycloak.org"/> -=== Exposing the server using a port other than the default ports +=== Backend -In this example, the server is accessible using a port other than the default ports. +The backend endpoints are those accessible through a public domain or through a private network. They're related to direct backend communication between {project_name} and a client (an application secured by {project_name}). Such communication might be over a local network, avoiding a reverse proxy. Examples of the endpoints that belong to this group are the authorization endpoint, token and token introspection endpoint, userinfo endpoint, JWKS URI endpoint, etc. -.{project_name} configuration: -<@kc.start parameters="--hostname-url=https://mykeycloak:8989"/> +The default value of `hostname-backchannel-dynamic` option is `false`, which means that the backchannel URLs are same as the frontchannel URLs. Dynamic resolution of backchannel URLs from incoming request headers can be enabled by setting the following options: -=== Exposing {project_name} behind a TLS reencrypt proxy using different ports +<@kc.start parameters="--hostname https://my.keycloak.org --hostname-backchannel-dynamic true"/> -In this example, the server is running behind a proxy and both the server and the proxy are using their own certificates, so the communication between {project_name} and the proxy is encrypted. The reverse proxy uses the `Forwarded` header and does not set the `X-Forwarded-*` headers. We need to keep in mind that the proxy configuration options (as well as hostname configuration options) are not changing the ports on which the server actually is listening on (it changes only the ports of static resources like JavaScript and CSS links, OIDC well-known endpoints, redirect URIs, etc.). Therefore, we need to use HTTP configuration options to change the {project_name} server to internally listen on a different port, e.g. 8543. The proxy will be listening on the port 8443 (the port visible while accessing the console via a browser). The example hostname `my-keycloak.org` will be used for the server and similarly the admin console will be accessible via the `admin.my-keycloak.org` subdomain. +Note that `hostname` option must be set to a URL. For more information, refer to the <> section below. -.{project_name} configuration: -<@kc.start parameters="--proxy-headers=forwarded --https-port=8543 --hostname-url=https://my-keycloak.org:8443 --hostname-admin-url=https://admin.my-keycloak.org:8443"/> +=== Administration + +Similarly to the base frontend URL, you can also set the base URL for resources and endpoints of the administration console. The server exposes the administration console and static resources using a specific URL. This URL is used for redirect URLs, loading resources (CSS, JS), etc. It can be done by setting the `hostname-admin` option: + +<@kc.start parameters="--hostname https://my.keycloak.org --hostname-admin https://admin.my.keycloak.org:8443"/> + +Again, the `hostname` option must be set to a URL. For more information, refer to the <> section below. + +== Sources for resolving the URL -WARNING: Usage of the `proxy-headers` option rely on `Forwarded` and `X-Forwarded-*` headers, respectively, that have to be set and overwritten by the reverse proxy. -Misconfiguration may leave {project_name} exposed to security issues. For more details, see <@links.server id="reverseproxy"/>. +As indicated in the previous sections, URLs can be resolved in several ways: they can be dynamically generated, hardcoded, or a combination of both: + +* Dynamic from an incoming request: +** Host header, scheme, server port, context path +** Proxy-set headers: `Forwarded` and `X-Forwarded-*` +* Hardcoded: +** Server-wide config (e.g `hostname`, `hostname-admin`, etc.) +** Realm configuration for frontend URL + +== Validations + +* `hostname` URL and `hostname-admin` URL are verified that full URL is used, incl. scheme and hostname. Port is validated only if present, otherwise default port for given protocol is assumed (80 or 443). +* In production profile (`kc.sh|bat start`), either `--hostname` or `--hostname-strict false` must be explicitly configured. +** This does not apply for dev profile (`kc.sh|bat start-dev`) where `--hostname-strict false` is the default value. +* If `--hostname` is not configured: +** `hostname-backchannel-dynamic` must be set to false. +** `hostname-strict` must be set to false. +* If `hostname-admin` is configured, `hostname` must be set to a URL (not just hostname). Otherwise {project_name} would not know what is the correct frontend URL (incl. port etc.) when accessing the Admin Console. +* If `hostname-backchannel-dynamic` is set to true, `hostname` must be set to a URL (not just hostname). Otherwise {project_name} would not know what is the correct frontend URL (incl. port etc.) when being access via the dynamically resolved bachchannel. == Troubleshooting @@ -146,11 +145,8 @@ To troubleshoot the hostname configuration, you can use a dedicated debug tool w .{project_name} configuration: <@kc.start parameters="--hostname=mykeycloak --hostname-debug=true"/> -Then after {project_name} started properly, open your browser and go to: - -`http://mykeycloak:8080/realms//hostname-debug` +After {project_name} starts properly, open your browser and go to: `http://mykeycloak:8080/realms//hostname-debug` .By default, this endpoint is disabled (`--hostname-debug=false`) -