When you run Keycloak in production, understanding how the internal port works is non‑negotiable. By default, Keycloak uses one port to handle internal traffic between its services and a separate port to handle public traffic. The “public” port is what your apps and users talk to. The internal one is for the server’s own management, admin console, or inter‑node communication in a cluster.
If you bind them wrong, you open your instance to security risks or break internal connections. Many run Keycloak in a containerized environment—Docker or Kubernetes—and forget that exposing the internal port can create problems. This port is often set with environment variables or configuration flags when you start the container, but the real trick is knowing what role it plays in the network model.
The internal port is usually bound to the loopback interface or an internal‑only address. This prevents the outside world from reaching it directly. Public reverse proxies like NGINX or Traefik connect to the public port, letting you manage TLS and routes without exposing administrative functions unnecessarily. In Keycloak’s newer releases, you can explicitly control internal and public binding addresses and ports, giving you a clean separation.
To change the internal port, you often modify --http-port and --https-port flags alongside --hostname-strict settings, but the key is making sure the port your cluster nodes talk to is not reachable externally. In Kubernetes, you define separate Services for public access and internal communication, often using ClusterIP for the internal one. This ensures the internal port is available only inside your virtual network.