What's the main difference between hub_connect_url vs hub_bind_url?

according to the docs:
hub_bind_url: The URL on which the Hub will listen. This is a private URL for internal communication.
hub_connect_url: The URL for connecting to the Hub. Spawners, services, and the proxy will use this URL to talk to the Hub.

We deploy jupyterhub inside a docker container, and therefore based on my understanding of the docs, here’s my settings:
c.JupyterHub.hub_bind_url = “”
c.JupyterHub.hub_connect_url = “http://EXTERNAL_IP:HOST_PORT”

so that the hub will bind on the CONTAINER_PORT inside the docker container.
For other services to link to it, it have to use http://EXTERNAL_IP:HOST_PORT

However, when I did this, the hub server keep register the to CHP, which is not accessible from external world, and therefore I can never go from CHP to the hub server itself.
Wondering if I misunderstand anything or this is a bug? (I am using jupyterhub 1.0.0, but 1.1.0 seems have exactly the same code on related files)

hub_bind_url is the URL passed to APIs such as socket.listen. This is what interface the socket is “bound to” or “listening on”. Most commonly, the ip has one of two values:

  1. for a single-host deployment. This will only work if the proxy and single-user servers are on the same host (or in the same container if you are using docker). This is the default value.
  2. for a multi-host (multi-container is multi-host) deployment, which means “all IPv4 interfaces”.

You can also specify a single LAN IP if you want to. This is typically useful in cluster scenarios where you want to avoid listening unnecessarily on publicly-accessible ips and only on the internal LAN.

In a container scenario, this will almost always want to be "" because other containers are “external” from a networking perspective due to docker’s virtual networking/namespaces.

hub_connect_url is the URL passed to other entities, such as the proxy or single-user servers when they connect to the Hub. This should use an ip or hostname that is connectable from the proxy and single-user servers. In Docker, this is often the name of the Hub container.

In docker, a common configuration would be:

c.JupyterHub.hub_bind_url = ""
c.JupyterHub.hub_connect_url = "http://hub-container-name:8081"

because docker-networking makes a container’s name its hostname, connectable from other containers on a shared docker network. Importantly, docker networking does not mean that binding on is publicly accessible on the host. Only within the docker network used by the Hub container.

The ports can (but typically do not) mismatch if you have routing layers in between, such as docker-swarm endpoints or kubernetes services, or other reverse-proxy layers. In those cases, you would use the listening port of the intermediate service in hub_connect_url rather than the port the Hub binds on.

Yup, sounds like this is probably a bug that when I have set up different hub_bind_url and hub_connect_url, the jupyterhub is register to CHP with hub_bind_url instead of hub_connect_url ?