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
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
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