8000 Make show_toolbar_with_docker work when host.docker.internal is not the gateway by lowbyteguy · Pull Request #2424 · django-commons/django-debug-toolbar · GitHub
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Make show_toolbar_with_docker work when host.docker.internal is not t…
…he gateway

show_toolbar_with_docker resolved host.docker.internal and shifted the last
octet to .1 to guess the Docker host address. On some runtimes, such as
OrbStack, that name resolves to an address unrelated to the container network
(0.250.250.254), so the computed address never matched REMOTE_ADDR and the
toolbar was never shown.

Add a second fallback that derives the candidate gateways from the container's
own addresses, keeping the existing host.docker.internal check first.

Fixes #2419
  • Loading branch information
lowbyteguy committed Jul 27, 2026
commit 7565446767e66e36368f4158c040fd6905fcea05
14 changes: 14 additions & 0 deletions debug_toolbar/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,20 @@ def show_toolbar_with_docker(request: HttpRequest) -> bool:
# It's fine if the lookup errored since they may not be using docker
pass

# Test: Docker, without relying on host.docker.internal
# Some runtimes (e.g. OrbStack) either do not provide host.docker.internal
# or resolve it to an address that is not the gateway. Fall back to
# guessing the gateway from the container's own addresses.
try:
container_ips = socket.gethostbyname_ex(socket.gethostname())[2]
except socket.gaierror:
# It's fine if the lookup errored since they may not be using docker
pass
else:
gateways = {ip.rsplit(".", 1)[0] + ".1" for ip in container_ips}
if request.META.get("REMOTE_ADDR") in gateways:
return True

# No test passed
return False

Expand Down
3 changes: 3 additions & 0 deletions docs/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ Pending

* Fixed the Django version check in the SQL panel test suite for Django's
boolean parameter handling.
* ``show_toolbar_with_docker`` now also guesses the Docker host from the
container's own addresses, so it works on runtimes such as OrbStack where
``host.docker.internal`` does not resolve to the gateway.

7.0.0 (2026-06-17)
------------------
Expand Down
17 changes: 17 additions & 0 deletions tests/test_integration.py
8154
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,23 @@ def test_show_toolbar_docker(self, mocked_gethostbyname):
self.assertTrue(show_toolbar_with_docker(self.request))
mocked_gethostbyname.assert_called_once_with("host.docker.internal")

@patch(
"socket.gethostbyname_ex",
return_value=("container", [], ["127.0.0.42"]),
)
@patch("socket.gethostbyname", return_value="0.250.250.254")
def test_show_toolbar_docker_gateway_fallback(
self, mocked_gethostbyname, mocked_gethostbyname_ex
):
"""host.docker.internal may not resolve to the host, e.g. on OrbStack.

Fall back to guessing the gateway from the container's own addresses.
"""
with self.settings(INTERNAL_IPS=[]):
self.assertFalse(show_toolbar(self.request))
self.assertTrue(show_toolbar_with_docker(self.request))
mocked_gethostbyname.assert_called_once_with("host.docker.internal")

def test_not_iterating_over_INTERNAL_IPS(self):
"""Verify that the middleware does not iterate over INTERNAL_IPS in some way.

Expand Down
Loading